结论
以 2026 年 8 月 17 日 的检索结果,严格按照你的判定标准:
只有响应中的省、市、区县、地址等地域字段明确出现 “昆山”/“昆山市”/“Kunshan”,才算正确。
最准的:https://update.cz88.net/iplab
已核验结果
| 数据源 | 查询结果 | 核验方式 | 判定 |
|---|---|---|---|
| ip2region 当前数据源 | 中国|江苏省|苏州市|电信 | 目标 IP 位于 180.103.128.0–180.103.255.255,该完整区间被标为苏州市 | ❌ 错误 |
| IP2Location DB26 | Jiangsu / Suzhou / Gusu Qu | 公开结果对应 180.103.xxx.0,其页面同时标明网段为 180.103.xxx.0/24;这是网段推断,并非 .130 的直接 API 请求 | ❌ 高概率错误 (IP2Location) |
| 其他国际库 | 通常只能到 Suzhou 或只到江苏省 | 未发现可核验的 Kunshan 目标响应 | 不计为通过 |
IP 地理位置中的“城市”本身是数据库估算值,并不是运营商提供的实时设备位置;部分服务自己的说明也将城市字段明确标为估算值。
最值得继续测试的接口
这些接口具备区县字段或使用国内地址库,有可能返回昆山,但在没有拿到目标响应前,我统一标为“待验证”。
| 优先级 | 接口 | 调用地址 | 说明 |
|---|---|---|---|
| P0 | IP9 | https://ip9.com.cn/get?ip=180.xxx.xxx.xxx | 无需密钥,响应有 prov、city、area 等字段;官方页面标注每 IP 每分钟免费 60 次。 |
| P0 | 太平洋电脑网 | https://whois.pconline.com.cn/ipJson.jsp?ip=180.xxx.xxx.xxx&json=true&level=3 | level=3 表示查询到省、市、区县;属于历史免费接口,没有正式 SLA。 |
| P0 | MoeIP | https://ip-moe.zerodream.net/?ip=180.xxx.xxx.xxx | 聚合纯真、ip2region、GeoIP2,多数据库结果适合横向对比。 |
| P1 | 1ip.io | https://1ip.io/api/180.xxx.xxx.xxx | 无需密钥,官方说明个人和商业用途均可免费调用。 |
| P1 | IPBot | https://api.ipbot.com/v1/ip/180.xxx.xxx.xxx | 无需密钥并支持 CORS,但主要定位到 city,不一定具备中国区县精度。 |
| P1 | 纯真 IPDB 离线库 | 非 HTTP API | 标准版有 region_name、city_name、district_name,当前公开版本为 2026.4.15,最适合放在后端本地查询。(npm) |
| 商用 | IP138 正式 API | http://api.ipshudi.com/ipdata/?ip=...&datatype=jsonp&token=... | 正式接口支持省、市、区及运营商,需要 Token,提供试用次数。(iP138查询网) |
百度 Qifu、Bilibili、淘宝、新浪等历史或未公开接口也放进了测试脚本,但它们没有面向开发者的稳定 SLA,不建议作为生产系统唯一数据源。
批量测试脚本
我已经整理了一份 Python 3.9+、不需要安装第三方库 的测试程序,共测试 26 个候选接口:
直接运行:
python ip_city_api_test.py指定超时和结果目录:
python ip_city_api_test.py 180.xxx.xxx.xxx \
--timeout 20 \
--output-dir resultsWindows 单行命令:
python ip_city_api_test.py 180.xxx.xxx.xxx --timeout 20 --output-dir results程序会并发请求所有接口,并输出:
PASS:响应正文或 JSON 地域字段明确出现昆山、昆山市或KunshanFAIL:接口正常返回,但没有出现昆山ERROR:超时、域名失效、HTTP 异常、证书问题或被限制- HTTP 状态码
- 请求耗时
- 命中的响应片段
Access-Control-Allow-Origin,用于判断 CORS- 完整的 JSON 和 UTF-8 BOM CSV 测试报告
脚本已通过 Python 语法检查和严格匹配规则测试。
生产环境建议
由于已知正确答案是昆山市,而多个主流库把该 IP 标成苏州市,业务上不能直接相信单一免费接口。建议采用下面的归一化方式:
IP_OVERRIDES = {
"180.xxx.xxx.xxx": {
"province": "江苏省",
"city": "昆山市",
"source": "manual_verified"
}
}只覆盖这个准确的 /32 地址,不要直接覆盖整个 180.103.xxx.0/24,因为目前没有证据表明整个网段都属于昆山。
正式查询链路建议为:
精确 IP 修正表
↓ 未命中
国内区县级数据库
↓ 无区县或接口异常
第二数据源交叉校验
↓
返回“苏州市(区县未知)”,不要伪造昆山市另外,这些接口应由你的 Python 后端统一代理调用,不要让 Vue 前端直接访问。浏览器端既可能被 CORS 拒绝,也可能像之前的 Bilibili 请求一样先被页面 CSP 的 connect-src 拦截;正式 API 的 Token 也不能暴露在前端。