身份证归属地查询:批量核验(Excel/CSV 导入)的循环调用设计
# 身份证归属地查询:批量核验(Excel/CSV 导入)的循环调用设计
> 接口:身份证归属地查询(apiCode=25,接入点 25-3) · 免费 · POST/GET · JSON · 适用人群:后端工程师、数据/运营 · 阅读时间:约 7 分钟
## TL;DR
- 本接口**没有批量接入点**,所谓"批量"= 客户端循环调用单号查询。
- 关键是:有限并发 + 限速 + 失败重试 + 结果回写,别一次性并发打满。
- 同一身份证重复出现时,配合缓存可省调用,见 [Redis 缓存篇](https://www.showapi.com/guides/idcard-attribution-cache-25)。
## Why
运营或数据同学常拿到一张 Excel/CSV,里面几千个身份证号,需要批量补出籍贯/生日/性别。本接口只提供单号查询,因此"批量"要在调用方自己实现:逐条(或有限并发)调用、收集结果、写回原表。
## What
| 项 | 值 |
|----|----|
| 批量方式 | 客户端循环调用单号查询(无服务端批量接入点) |
| 推荐节奏 | 有限并发 + 间隔,避免触发平台频率限制 |
| 失败处理 | 单条失败标记重试,不中断整体 |
## How
### 步骤 1:读取表格
用 `pandas` 读取 CSV/Excel,取出身份证号列。
### 步骤 2:有限并发 + 限速 + 重试
```python
import time
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
APP_KEY = "YOUR_APPKEY"
URL = "https://route.showapi.com/25-3"
def query_one(id_number: str, retries: int = 3) -> dict:
for attempt in range(retries):
try:
resp = requests.post(URL, params={"appKey": APP_KEY},
data={"id": id_number}, timeout=10)
data = resp.json()
if data.get("showapi_res_code") != 0:
raise RuntimeError(data.get("showapi_res_error"))
body = data["showapi_res_body"]
if body.get("ret_code") != 0:
raise RuntimeError(body.get("retMsg"))
return {"id": id_number, **body["retData"], "status": "ok"}
except Exception as e:
if attempt == retries - 1:
return {"id": id_number, "status": "fail", "error": str(e)}
time.sleep(0.5 * (2 ** attempt)) # 指数退避
def batch_query(ids: list, workers: int = 5):
results = []
with ThreadPoolExecutor(max_workers=workers) as ex:
futures = {ex.submit(query_one, i): i for i in ids}
for f in as_completed(futures):
results.append(f.result())
time.sleep(0.1) # 简单限速,避免打满
return results
```
### 步骤 3:回写结果
将 `results` 合并回原 DataFrame,导出新文件。
## 返回示例
单条返回结构同 [返回字段全解](https://www.showapi.com/guides/idcard-attribution-fields-25),批量时只是把每条结果汇总。
## 进阶 / 边界
- **没有"批量订阅+回调"**:本接口是纯同步单号查询,不存在异步批量模型,不要按订阅/回调方式设计。
- **限速优先于并发**:免费接口仍受平台频率约束,`workers` 与 `sleep` 按实际体感调整,先小批量试跑。
- **去重 + 缓存**:若同一批里有重复身份证,先去重再查,命中缓存直接返回,见缓存篇。
- **断点续跑**:大批量建议按批次落盘中间结果,失败批次可单独重跑。
## FAQ
**Q:接口支持一次传多个 id 吗?**
不支持。文档仅提供单号查询接入点,批量需在调用方循环实现。
**Q:并发开多大合适?**
没有官方固定值;建议从小(如 5)开始试跑,观察是否触发限流再调整。本文不给出具体上限数字。
**Q:批量会收费吗?**
接口本身免费;但"批量"意味着多次调用,仍受平台频率约束,注意节奏。
**Q:中途失败怎么处理?**
单条失败按重试 + 标记,不影响整体;建议记录失败清单供补跑。
**Q:能不能用订阅/回调做异步批量?**
不能。本接口无订阅推送与回调能力,只有同步查询。
## 相关能力 / 下一步阅读
- [身份证归属地查询:用 Redis 缓存降低重复查询与频率限制风险](https://www.showapi.com/guides/idcard-attribution-cache-25)
- [身份证归属地查询:调用前如何先做身份证号格式与校验位合法性自检](https://www.showapi.com/guides/idcard-attribution-input-check-25)
- [身份证归属地查询:错误处理与排错(showapi_res_code / ret_code 通用处理)](https://www.showapi.com/guides/idcard-attribution-errors-25)
- **本系列共 12 篇**:查看[身份证归属地查询指南总目录](https://www.showapi.com/guides/idcard-attribution-guides-25)