跳到主要内容

IP归属地查询

收藏0

查询 IP 地址归属地(国家、省份、城市、运营商、ASN、时区、经纬度),支持查本机公网 IP、传域名自动解析、批量查询。无需 API Key,数据来自 ip-api.com 免费接口。

让 AI 安装

Minsaroun最新版本 0.1.0更新于 2026-11-02下载 1 次

ipinfo.py

3.2 KB
1#!/usr/bin/env python3
2# IP 归属地查询(ip-api.com 免费 API,无需 Key)
3import argparse, json, socket, sys, urllib.parse, urllib.request
4
5API = 'http://ip-api.com/json'
6FIELDS = 'status,message,country,countryCode,regionName,city,isp,org,as,asname,timezone,lat,lon,query'
7
8
9def fetch(url):
10 req = urllib.request.Request(url, headers={'User-Agent': 'ip-geolocation-skill/1.0'})
11 with urllib.request.urlopen(req, timeout=15) as r:
12 return json.loads(r.read().decode())
13
14
15def lookup(ip, lang):
16 params = {'lang': lang, 'fields': FIELDS}
17 q = urllib.parse.urlencode(params)
18 return fetch(f'{API}/{ip}?{q}')
19
20
21def resolve(host):
22 try:
23 return socket.gethostbyname(host)
24 except socket.gaierror:
25 return None
26
27
28def fmt_ip(ip, lang):
29 data = lookup(ip, lang)
30 if data.get('status') != 'success':
31 return f'{ip}: 查询失败({data.get("message", "unknown")})'
32 lines = [ip]
33 country = data.get('country', '')
34 cc = data.get('countryCode', '')
35 if lang == 'zh':
36 if cc:
37 lines.append(f' 国家:{country}({cc})')
38 region = data.get('regionName', '')
39 city = data.get('city', '')
40 loc = f'{region} {city}'.strip()
41 if loc:
42 lines.append(f' 地区:{loc}')
43 isp = data.get('isp', '')
44 org = data.get('org', '')
45 if isp:
46 lines.append(f' 运营商:{isp}' + (f'({org})' if org and org != isp else ''))
47 asn = data.get('as', '')
48 if asn:
49 lines.append(f' ASN:{asn}')
50 tz = data.get('timezone', '')
51 if tz:
52 lines.append(f' 时区:{tz}')
53 lat, lon = data.get('lat'), data.get('lon')
54 if lat is not None and lon is not None:
55 lines.append(f' 坐标:{lat}, {lon}')
56 else:
57 if cc:
58 lines.append(f' Country: {country} ({cc})')
59 loc = ' '.join(x for x in (data.get('regionName', ''), data.get('city', '')) if x)
60 if loc:
61 lines.append(f' Region: {loc}')
62 if data.get('isp'):
63 lines.append(f' ISP: {data["isp"]}')
64 if data.get('as'):
65 lines.append(f' ASN: {data["as"]}')
66 if data.get('timezone'):
67 lines.append(f' Timezone: {data["timezone"]}')
68 if data.get('lat') is not None:
69 lines.append(f' Lat/Lon: {data["lat"]}, {data["lon"]}')
70 return '\n'.join(lines)
71
72
73def main():
74 p = argparse.ArgumentParser(description='IP 归属地查询')
75 p.add_argument('targets', nargs='*', help='IP 或域名(留空=查本机公网 IP)')
76 p.add_argument('--lang', choices=['zh', 'en'], default='zh')
77 a = p.parse_args()
78
79 targets = a.targets or ['']
80 if len(targets) > 100:
81 print('最多一次查 100 个地址')
82 sys.exit(1)
83
84 out = []
85 for t in targets:
86 ip = t.strip()
87 if not ip:
88 ip = ''
89 elif not ip.replace('.', '').isdigit():
90 resolved = resolve(ip)
91 if not resolved:
92 out.append(f'{ip}: 域名解析失败')
93 continue
94 ip = resolved
95 out.append(fmt_ip(ip, a.lang))
96 print('\n\n'.join(out))
97
98
99if __name__ == '__main__':
100 main()

文件内容是平台检查时读出的文本,只供查看。平台不会运行包里的任何脚本或程序。