
适用场景当业务需要根据客户端 IP 还原更精细的位置信息时普通的城市级定位往往不够用。比如物流网点推荐、本地生活内容分发、异常登录提示等场景如果只知道城市可能把福州市区的用户推荐到闽侯县的网点。这时候就需要街道级 IP 定位能力。本文要演示的接口是 IP 地址查询街道级它返回的不只是经纬度还包括省份、城市、区县、街道、ISP 运营商、邮编、区号等信息并附带一个风险评分对象用于判断该 IP 是否来自代理或存在异常行为。接口能力边界先明确这个接口能做什么、不能做什么支持 IPv4 与 IPv6 地址查询。不传ip参数时自动使用调用方自身 IP适合“查我自己”的调试场景。响应中的数据来自多数据源自动切换主源提供街道 ISP 风险评分主源不可用时自动降级到备用源城市级 ISP。返回结果中的data.source字段标记本次命中的是primary主源还是备选源调用方可以根据这个字段判断数据的精细程度。该接口的 QPS 限制为 3 次/秒超过限制会出现限流错误。值得强调的是街道级定位不等于 GPS 定位street字段通常表示 IP 归属登记地址所在的街道而不是用户当前实际所处的精确位置。在业务设计上应把它理解为“网络出口所在地”而不是“人所在的位置”。请求参数与鉴权Query 参数参数类型必填说明ipstring否要查询的 IP 地址IPv4 或 IPv6。不传时自动使用调用方自身 IP示例值110.87.41.14Header 参数参数类型必填说明Authorizationstring否Bearer Token。匿名调用时可省略但受每日匿名额度限制付费方案或超过额度时必需示例值Bearer sk_live_xxxxxxxxxxxxxxxx注意文档中的 curl 示例使用的是X-API-Key请求头而参数表里给出的是Authorization: Bearer方式。实际接入时以文档页最新说明为准建议两种方式都在本地做一次连通性验证。最小可运行示例curl 请求以下 curl 命令演示了查询指定 IP 的最简方式curl -sS \ -X GET \ -H Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx \ https://v1.apizero.cn/api/ip-pro?ip110.87.41.14如果没有 Token可以先去掉Authorization请求头做匿名调用curl -sS https://v1.apizero.cn/api/ip-pro?ip110.87.41.14如果不想手动拼 URL也可以把ip单独拎出来用--get与--data-urlencode组合避免特殊字符转义问题curl -sS \ --get \ --data-urlencode ip110.87.41.14 \ https://v1.apizero.cn/api/ip-pro返回的响应是 JSON 数组外层数组中的每个元素包含status、description、content_type和example字段。example里的结构才是真正需要关注的业务数据。返回字段解读以素材中的响应示例为例data对象的部分关键字段如下字段类型含义ipstring实际查询的 IP 地址continentstring大洲名称如“亚洲”countrystring国家名称country_codestring国家代码如CNprovincestring省份citystring城市districtstring区县streetstring街道street_alternativesstring[]可能的候选街道列表因为 IP 库对街道的推断存在多候选情况ispstring运营商如“电信”latitudenumber纬度longitudenumber经度area_codestring行政区划代码city_codestring电话区号zip_codestring邮政编码time_zonestring时区elevationnumber海拔米riskobject风险评分信息sourcestring数据来源档位primary表示主源risk 对象结构risk字段是整个响应中比较有特色的部分它包含is_proxy布尔值是否代理 IP。proxy_probability代理概率取值范围通常是 0 到 1 之间的小数。score综合风险分示例中为0。level风险等级文案如“无风险”。mobile_rate移动网络占比。real_rate真实用户占比。在示例中proxy_probability为0score为0说明该 IP 被判定为低风险。在风控场景中可以先判断score是否超过业务阈值再结合is_proxy做二次确认而不应该只依赖某一个字段。数据降级source 字段的含义接口说明里提到“多数据源自动切换”这是接入时最容易忽略的一点。当主源可用时data.source为primary此时street、street_alternatives、risk等街道级和风险相关字段通常都有值。当主源不可用时接口自动降级到备用源。降级后的数据可能是城市级street字段可能为空risk对象也可能不完整。这时候如果业务强依赖街道字段就需要做兜底处理。一个简单的处理策略是检查data是否为空。检查data.source是否为primary。如果source不是primary则降低对street和risk字段的信任等级。调用方可以根据自身业务决定是接受城市级结果还是标记为“定位精度不足”。{ data: { source: backup, street: , risk: null } }注意上面这个 JSON 是降级场景的示意结构不代表真实响应一定会把risk置为null请以接口实际返回为准。错误处理与排查思路遇到异常响应时先看 HTTP 状态码再看响应体中的code与msg字段。素材中没有给出完整的错误码表但可以根据经验按以下顺序排查1. 鉴权失败如果省略了Authorization或X-API-Key且当日匿名额度已用完接口可能返回 401 或业务错误码。排查时先确认请求头中的 Key 是否有效注意区分Bearer前缀与X-API-Key两种传递方式。2. IP 格式错误ip参数传入的不是合法 IPv4/IPv6 地址时接口可能返回参数校验错误。建议在调用前用简单的正则或内置库做格式校验import ipaddress try: ipaddress.ip_address(110.87.41.14) except ValueError: print(invalid ip)3. 限流触发该接口 QPS 为 3也就是每秒最多处理 3 次请求。如果业务需要批量查询直接循环调用很容易触发限流。一个简单的节流方式是在循环中休眠import time import requests url https://v1.apizero.cn/api/ip-pro headers {Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx} for ip in ip_list: resp requests.get(url, params{ip: ip}, headersheaders) print(resp.status_code, resp.text) time.sleep(0.4)这里的time.sleep(0.4)把请求频率控制在每秒 2.5 次左右留出一定余量。更稳健的做法是使用令牌桶算法做限流但要注意请求频率按接口维度控制而不是按单个 IP 维度。4. 街道字段缺失如果请求成功但street为空可能是主源降级导致的。此时应读取source字段确认数据档位而不是直接判断接口异常。工程化注意事项缓存策略IP 地理信息在短时间内变化不大同一个 IP 重复查询会浪费 QPS。建议在业务层增加缓存例如对查询结果缓存 24 小时。缓存 key 可以使用ip:110.87.41.14这种形式value 直接存放整个data对象。超时与重试外部接口调用必须设置超时时间。建议连接超时 3 秒、读取超时 5 秒。重试时要考虑限流因素不要对限流错误做无退避的重试。字段兼容响应结构可能随着主备源切换而变化。在解析 JSON 时不要直接假设data.street一定存在建议使用dict.get(street, )这类安全访问方式。street data.get(street) or unknown risk_score (data.get(risk) or {}).get(score, -1)日志记录建议把request_id、ip、source三个字段写入日志。request_id用于请求链路追踪source用于判断数据精度ip用于业务审计。参考文档接口文档https://apizero.cn/aidocs/ip-pro原始 Markdown 文档https://apizero.cn/aidocs/ip-pro/raw.md