From a689e66635b04eb918a31bb98e4002c67632fd47 Mon Sep 17 00:00:00 2001 From: PAN Lei Date: Mon, 1 Dec 2025 14:34:07 +0100 Subject: [PATCH] use FreeIPAPI.py to get ip's geo information --- utils/FreeIPAPI.py | 106 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 utils/FreeIPAPI.py diff --git a/utils/FreeIPAPI.py b/utils/FreeIPAPI.py new file mode 100644 index 0000000..ac3c917 --- /dev/null +++ b/utils/FreeIPAPI.py @@ -0,0 +1,106 @@ +import requests +import json +import sys + +def get_ip_geolocation(ip_address=None): + """ + 使用 FreeIPAPI 查询指定 IP 地址的地理位置信息。 + 如果没有提供 IP 地址,将查询请求本身的公网 IP。 + + Args: + ip_address (str, optional): 要查询的 IP 地址。默认为 None。 + + Returns: + dict: 包含 IP 信息的字典,如果请求失败则返回 None。 + """ + base_url = "https://freeipapi.com/api/json" + + if ip_address: + # 如果指定了 IP,则在 URL 中添加 IP + url = f"{base_url}/{ip_address}" + else: + # 如果未指定 IP,则查询发起请求的 IP + url = base_url + + print(f"正在查询 IP: {ip_address if ip_address else '当前公网 IP'}...") + + try: + # 发送 GET 请求,设置超时时间 + response = requests.get(url, timeout=10) + + # 检查 HTTP 状态码,如果不是 200 则抛出异常 + response.raise_for_status() + + # 解析 JSON 响应 + data = response.json() + + # 检查 API 是否返回了错误信息(FreeIPAPI 在某些情况下会返回 status: 404) + if data.get('status') == 404: + print(f"查询失败:FreeIPAPI 报告未找到该 IP 地址的信息。") + return None + + return data + + except requests.exceptions.RequestException as e: + print(f"请求失败,发生网络错误: {e}") + return None + except json.JSONDecodeError: + print("响应解析失败,可能不是有效的 JSON 格式。") + return None + +def display_ip_info(data): + """ + 格式化并打印 IP 地址信息。 + """ + if not data: + print("无法获取 IP 信息。") + return + + print("\n--- IP 地理位置信息 ---") + + # 使用 .get() 方法安全地获取数据,避免 KeyError + print(f"IP 地址: {data.get('ipAddress', 'N/A')}") + print(f"国家: {data.get('countryName', 'N/A')}") + print(f"国家代码: {data.get('countryCode', 'N/A')}") + print(f"城市: {data.get('cityName', 'N/A')}") + print(f"邮编: {data.get('zipCode', 'N/A')}") + print(f"时区: {data.get('timeZone', 'N/A')}") + # 经纬度 + latitude = data.get('latitude', 'N/A') + longitude = data.get('longitude', 'N/A') + print(f"纬度/经度: {latitude} / {longitude}") + print(f"ISP/组织: {data.get('isp', 'N/A')}") + print("------------------------") + + +def main(): + """ + 主执行函数。可以接受命令行参数作为要查询的 IP 地址。 + """ + # 检查是否有命令行参数传入 + if len(sys.argv) > 1: + # 取第一个参数作为要查询的 IP 地址 + ip_to_query = sys.argv[1] + print(f"检测到命令行参数: {ip_to_query}") + + ip_info = get_ip_geolocation(ip_to_query) + display_ip_info(ip_info) + + else: + # 1. 查询当前公网 IP (不传参数) + print("\n--- 示例 1: 查询当前公网 IP ---") + my_ip_info = get_ip_geolocation() + display_ip_info(my_ip_info) + + # 2. 查询特定 IP 地址 (例如:Google 的 DNS 服务器 8.8.8.8) + print("\n--- 示例 2: 查询特定 IP 地址 (8.8.8.8) ---") + google_dns_ip = "8.8.8.8" + google_ip_info = get_ip_geolocation(google_dns_ip) + display_ip_info(google_ip_info) + + +# 脚本入口点 +if __name__ == "__main__": + ip_info = get_ip_geolocation("80.13.246.205") + print(ip_info) + display_ip_info(ip_info) \ No newline at end of file