最小可运行示例:用手机号归属地查询 API 快速获取省份与运营商
适用场景
在用户准备、短信发送、风险控制或号码标记等环节,经常需要根据手机号判断其归属省份与运营商。手机号归属地查询 API 提供了一种标准化的方式,输入 11 位手机号即可返回 province、carrier 等字段,无需维护本地号段数据。本文围绕该 API 的最小可运行示例展开,直接从请求构造入手,配合 curl 和代码演示,让读者在 5 分钟内跑通一次调用。
接口能力边界
- 输入校验:严格匹配正则
^1[3-9]\d{9}$,非 11 位或开头非 1[3-9] 的号码会被拒绝并返回 4000 错误码。 - 双形态响应:查询成功时
is_found为true,且province、carrier填充具体值;若号段尚未收录(例如新放出的号段),则is_found为false,其余字段为空字符串——此时仍属于成功请求(HTTP 200,code 0),前端可以依据is_found做 UI 降级,无需额外错误分支。 - 缓存策略:成功结果缓存 7 天(因为号段分配相对静态),未查询到的结果缓存 1 小时(避免对新号段产生过长误判)。该策略由服务端自动执行,调用方无需关心。
- 隐私保护:服务端错误日志中手机号会自动脱敏(如 138****0000),调用方在本地打印日志时也应遵循类似脱敏策略。
该接口覆盖中国移动、联通、电信主流号段及虚拟运营商号段(170/171/174 等),但不支持港澳台及境外号码。
请求参数与鉴权
Query 参数
| 参数名 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
mobile | 是 | string | 11 位中国大陆手机号,必须以 1[3-9] 开头 | 13800138000 |
Header 鉴权
接口支持两种鉴权方式(二选一):
- Authorization 头(推荐):格式
Bearer sk_live_xxx,其中sk_live_xxx是你在 API 平台获取的密钥。 - X-API-Key 头(兼容):格式
sk_live_xxx,不含 Bearer 前缀。
匿名调用(不传任何鉴权头)每日有 50 次调用次数限制,适合测试阶段快速体验;生产环境建议使用密钥鉴权以避免次数受限。
最小可运行 curl 示例
以下命令直接在终端执行即可调用接口(请将$YOUR_API_KEY替换为实际密钥):
curl -sS \ -X GET \ -H "Authorization: Bearer $YOUR_API_KEY" \ "https://v1.apizero.cn/api/mobile?mobile=13800138000"若使用兼容头:
curl -sS \ -X GET \ -H "X-API-Key: $YOUR_API_KEY" \ "https://v1.apizero.cn/api/mobile?mobile=13800138000"免鉴权测试(不传任何 Key 头,每日 50 次):
curl -sS \ -X GET \ "https://v1.apizero.cn/api/mobile?mobile=13800138000"执行后会看到类似 JSON 输出:
{ "code": 0, "data": { "carrier": "中国移动", "is_found": true, "mobile": "13800138000", "province": "北京" }, "msg": "成功", "request_id": "abc123def456" }Python 代码接入示例
下面是一个完整的 Python 3 脚本,包含函数封装、异常处理和日志脱敏建议:
import requests import re def query_mobile_phone(mobile: str, api_key: str = "") -> dict: """ 查询手机号归属地 :param mobile: 11 位手机号 :param api_key: API 密钥,为空时使用匿名调用(每日 50 次) :return: 原始响应 JSON(dict) """ # 前置校验:避免无效请求浪费配额 if not re.match(r'^1[3-9]\d{9}$', mobile): raise ValueError(f"无效手机号格式: {mobile}") url = "https://v1.apizero.cn/api/mobile" params = {"mobile": mobile} headers = {} if api_key: headers["Authorization"] = f"Bearer {api_key}" # 注意:日志中手机号脱敏处理,只记录前三位和后四位 safe_mobile = mobile[:3] + "****" + mobile[-4:] print(f"[INFO] 正在查询手机号: {safe_mobile}") resp = requests.get(url, params=params, headers=headers, timeout=10) resp.raise_for_status() # 非 2xx 状态码会抛出异常 return resp.json() if __name__ == "__main__": # 测试:使用真实号码(可换成你自己的号) result = query_mobile_phone("13800138000", api_key="") print(result)运行该脚本(需要requests库,可用pip install requests安装),输出类似:
{ "code": 0, "data": { "carrier": "中国移动", "is_found": true, "mobile": "13800138000", "province": "北京" }, "msg": "成功", "request_id": "req_xxxxxxxxxxxx" }返回值解读
响应体始终为 JSON,顶层字段固定:
| 字段 | 类型 | 说明 |
|---|---|---|
code | number | 业务状态码,0 表示成功,非 0 见错误码表格 |
msg | string | 对应 code 的中文描述 |
data | object | 查询结果数据 |
request_id | string | 本次请求的全局唯一标识,可用于排查问题 |
data中字段:
| 字段 | 类型 | 说明 |
|---|---|---|
mobile | string | 传入的手机号原值 |
is_found | boolean | 是否找到归属信息 |
province | string | 省份(如“广东”);is_found为 false 时为空字符串 |
carrier | string | 运营商(如“中国移动”“中国联通”“中国电信”或“虚拟运营商”);未查到时为空 |
常见错误码解析
| code | msg | 触发条件 | 排查方向 |
|---|---|---|---|
| 0 | 成功 | 请求完全正常 | – |
| 4000 | 参数错误(手机号格式无效) | mobile 不符合 11 位数字或开头非 1[3-9] | 检查前端输入校验,截取前后空格 |
| 4001 | 缺少必要参数 | 未传 mobile 参数 | 确认 URL query 中是否包含 mobile |
| 4010 | 鉴权失败 | Authorization 头格式不对或密钥无效 | 检查 Bearer 前缀、密钥是否有权限 |
| 4030 | 频率限制 | 请求 QPS 超过 10 次/s | 在客户端实现限流,或改用异步队列 |
| 5000 | 服务器内部错误 | 服务端异常 | 联系服务商并提供 request_id |
注意:当
is_found=false时返回的仍是 code=0,不属于错误,前端应直接通过if (!data.is_found) { ... }处理。
工程化注意事项
- 参数校验前置:在发送 HTTP 请求前先对手机号做正则校验,避免无效请求浪费配额并降低延迟。
- 日志脱敏:无论在服务端还是客户端,记录日志时应将手机号中间四位替换为
****,避免泄露用户隐私。接口本身已对错误日志做脱敏,但调用方自身也需注意。 - 缓存策略配合:接口服务端已内置 7 天缓存(成功结果),因此客户端无需再对相同号码做额外缓存;但对于未查询到的结果(
is_found=false),客户端可考虑本地短暂缓存(如 10 分钟)以减少重复查询。 - 并发限流:接口 QPS 为 10/s,如果同时有大量查询需求,应在客户端进行令牌桶限速或排队。使用异步 HTTP 客户端(如 aiohttp)可以批量发送请求但需注意控制速率。
- 错误重试:对于 5xx 错误(如 5000),可间隔 1~2 秒重试至多 2 次;对于 4xx 错误(如 4000、4010)不应重试,应修复请求参数。
- 测试号码:开发阶段可使用
13800138000等公开测试号,但生产环境中需确保手机号来源合法合规。
参考文档
- 官方文档页:https://apizero.cn/aidocs/mobile
- 原始 Markdown 文档:https://apizero.cn/aidocs/mobile/raw.md
