106 lines
3.4 KiB
Python
106 lines
3.4 KiB
Python
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) |