资讯动态

把身份证识别做成内部工具:请求规范、字段校验与限流设计

发布时间:2026/8/9 15:40:36 来源:尧图企业网站定制
使用场景把身份证识别嵌进业务系统做实名认证、员工入职、会议室访客登记这类需求时常见的做法是让用户手动上传身份证图片再让运营同学人工录入。这种方式在数据量小的时候还能接受一旦每天几百单人工录入速度就会成为瓶颈。把身份证识别接口包成团队内部的一个小工具服务前端上传图片后端调用识别接口拿到结构化字段后回填表单可以省掉大量重复手工操作。本文以身份证识别接口为例说明从请求构造到字段消费的完整链路以及接入时容易踩的坑。接口能力边界在使用之前先明确它做什么、不做什么输入一张身份证正面或反面图片可通过图片 URL 或 base64 字符串传入格式jpg/pngbase64 格式最大 10 MB输出姓名、身份证号、性别、民族、出生日期、地址、签发机关、有效期起止、正反面标记共 10 个字段有几个边界需要留意接口支持正反面自动判断但返回的字段与图片内容有关正面图片一般不会返回签发机关和有效期QPS 为 2 /s即单连接下每秒最多 2 个请求超限后请求是否被拒绝要以文档描述为准接口需要登录后使用鉴权时要在 Header 中携带 API Key属于私有接口不是匿名开放调用鉴权方式接口要求的 Header 如下AuthorizationBearer 你的 API KeyContent-Typeapplication/json在部分文档示例中鉴权 Header 写作X-API-Key: $APIZERO_API_KEY。接入前建议以文档页当前说明为准优先使用 Authorization 标准写法如果服务端验证不通过再对照文档确认实际接收的 Header 名。curl 接入示例下面是一个可直接复制的 curl 请求模板把 API Key 替换成你自己的值图片地址换成一张真实可访问的 jpg/png 图片export IDCARD_OCR_URLhttps://v1.apizero.cn/api/ocr-idcard export APIZERO_API_KEYyour_api_key_here curl -sS \ -X POST \ -H X-API-Key: $APIZERO_API_KEY \ -H Content-Type: application/json \ -d { input_type: url, input_data: https://example.com/idcard-front.jpg } \ $IDCARD_OCR_URL请求体只有两个字段input_type固定传url或base64input_data图片 URL或 base64 编码后的字符串需要注意URL 指向的图片必须可以直接访问带防盗链、需要登录、签名过期的图片地址都会导致识别失败。Python 代码接入实际项目中通常不会直接调 curl而是封装成一个函数。下面是使用 requests 的完整示例支持本地文件自动转 base64 后传入import base64 import json import os import requests OCR_URL https://v1.apizero.cn/api/ocr-idcard API_KEY os.environ[APIZERO_API_KEY] def image_path_to_base64(path: str) - str: with open(path, rb) as f: return base64.b64encode(f.read()).decode(utf-8) def recognize_idcard(base64_str: str) - dict: payload { input_type: base64, input_data: base64_str } headers { X-API-Key: API_KEY, Content-Type: application/json } resp requests.post(OCR_URL, jsonpayload, headersheaders, timeout10) resp.raise_for_status() return resp.json() if __name__ __main__: result recognize_idcard(image_path_to_base64(idcard-front.jpg)) print(json.dumps(result, ensure_asciiFalse, indent2))注意两点base64 编码后的字符串会比原文件大建议在编码前先检查原文件大小避免超过接口的 10 MB 限制这里设置的timeout10是客户端超时不等于接口的响应时限具体以文档为准返回字段解读成功响应示例{ code: 0, msg: 成功, request_id: req_abc123, data: { address: 上海市浦东新区某某路123号, birth: 1990-01-01, gender: 男, identity_code: 310101199001011234, identity_name: 张三, issued_by: null, race: 汉, side: 1, valid_date_end: null, valid_date_start: null } }外层字段code业务状态码0 表示成功msg描述信息request_id单次请求的唯一标识排查问题时把该值发给服务端定位日志data内层字段如下表所示字段含义示例值identity_name姓名张三identity_code身份证号310101199001011234gender性别男race民族汉birth出生日期1990-01-01address地址上海市浦东新区某某路123号issued_by签发机关反面字段nullvalid_date_start有效期开始日期反面字段nullvalid_date_end有效期结束日期反面字段nullside正反面标记1在上面的示例中issued_by、valid_date_start、valid_date_end都是 null说明该图片是身份证正面服务端没有返回反面字段。素材中side为 1但正面与反面具体对应哪个枚举值以文档为准。业务侧消费字段时不能假定每次调用都会返回全部 10 个字段要先根据side判断图片方向再决定使用哪些字段。常见错误与排查思路错误可以分成三层来看第一层HTTP 状态异常401 UnauthorizedAPI Key 缺失或无效检查是否拼写错误、是否带上 Bearer 前缀或 X-API-Key 前缀404请求 URL 写错核对接口地址是否为/api/ocr-idcard429请求频率超过 QPS 限制退避重试或本地排队第二层业务码非 0code不为 0 时msg一般会给出具体原因。常见问题集中在图片本身图片不是 jpg/png或文件是 jpg 但扩展名被改成 png图片模糊、反光、有遮挡导致 OCR 无法抽取字段图片 URL 访问超时或返回非图片内容第三层字段为空或为 null这不算调用失败但业务上需要处理。例如正面图片没有issued_by需要在代码中判空不能直接组装成完整结果写入数据库。def build_identity_record(data: dict) - dict: return { name: data.get(identity_name), id_code: data.get(identity_code), side: data.get(side), issued_by: data.get(issued_by) or , valid_start: data.get(valid_date_start) or , valid_end: data.get(valid_date_end) or }工程化注意事项1. QPS 2/s 的应对方案如果业务流量超过每秒 2 次直接在同步调用链里打接口会被限流。常见做法是在服务内加一个局部限流器把请求放入队列以不超过 2 QPS 的速度消费也可以在前端做文件预检和质量校验减少无效调用。2. 身份证号字段校验OCR 偶尔会识别出错尤其是身份证号这种关键字段。可以在入库前做一次本地校验身份证号是 18 位前 17 位是数字最后一位可能是数字或 X。下面是一个通用校验算法实现def validate_identity_code(code: str) - bool: if not code or len(code) ! 18: return False weights [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] check_chars 10X98765432 try: total sum(int(code[i]) * weights[i] for i in range(17)) except ValueError: return False return code[17] check_chars[total % 11]校验通过后再存入业务表校验失败时可以进入人工复核队列而不是直接拒绝用户。3. 日志与敏感数据脱敏身份证图片、身份证号属于敏感个人信息。有以下几条建议接口日志中不要打印完整identity_code只保留前 3 位和后 4 位不把原图直接写入业务日志若必须保存使用单独的对象存储权限request_id单独记录方便追溯调用链路def mask_id_code(code: str) - str: if not code or len(code) 8: return *** return code[:3] * * 11 code[-4:]4. 正面反面区分处理只拿到正面时issued_by、valid_date_start、valid_date_end都是 null。业务流程需要分别为正面识别和反面识别设计分支避免用 null 覆盖已有数据。5. 重试策略网络波动导致的超时属于可重试错误但要注意两点对同一个请求建议使用相同的request_id或记录原始图片 hash避免重复扣接口调用重试次数建议限制在 2 次以内重试间隔递增比如 200ms、800ms参考文档接口文档页https://apizero.cn/aidocs/ocr-idcard原始文档Markdownhttps://apizero.cn/aidocs/ocr-idcard/raw.md

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价