适用场景与业务价值
在企业运营、电商入驻、餐饮供应链管理或食品经营资质审核中,经常需要人工核对食品经营许可证上的关键字段,如许可证编号、经营者名称、法定代表人、经营场所、主体业态、经营项目及有效期等。传统人工录入效率低、易出错,通过API自动识别证件字段可以显著提升审核速度与准确性。
接口能力边界
- 接口名称:食品经营许可证识别(slug: food-license)
- 请求方式:POST
- 请求地址:
https://v1.apizero.cn/api/food-license - 输入方式:支持图片URL或Base64编码字符串(Base64最大限制5MB)
- 输出字段:共13个字段(详见返回值解读)
- QPS限制:2次/秒
- 分类:文档识别
注意:该接口仅适用于中国大陆现行的食品经营许可证(《食品经营许可证》样式),其他地区或历史版本证件可能无法识别。图片需清晰、光照均匀,文字无遮挡,否则识别质量会下降。
鉴权与请求参数
Header设置
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Content-Type | 是 | string | 固定为application/json |
| X-API-Key | 是 | string | 你的API密钥(Bearer令牌或key参数也可通过请求体传递) |
请求体(JSON对象)
| 字段名 | 必填 | 类型 | 说明 |
|---|---|---|---|
| key | 否 | string | API密钥,与Header中的X-API-Key二选一;建议统一使用Header方式传递 |
| input_type | 是 | string | 图片传入方式:url(图片链接)或base64(Base64编码字符串) |
| input_data | 是 | string | 图片URL地址(input_type=url)或Base64字符串(input_type=base64) |
字段
key虽然在请求体中是非必填,但实际鉴权必须提供有效密钥。推荐优先使用X-API-Key请求头传递,更符合标准RESTful实践。
快速接入:curl示例
以下命令使用X-API-Key鉴权,并传入图片URL(假设图片为公开可访问的食品经营许可证照片)。
curl -sS \ -X POST \ -H "X-API-Key: YOUR_API_KEY_HERE" \ -H "Content-Type: application/json" \ -d '{ "input_type": "url", "input_data": "https://example.com/images/food-license-sample.jpg" }' \ "https://v1.apizero.cn/api/food-license"如果使用Base64方式,需先对图片文件进行Base64编码,注意去除换行符:
BASE64_STR=$(base64 -w0 /path/to/license.jpg) curl -sS \ -X POST \ -H "X-API-Key: YOUR_API_KEY_HERE" \ -H "Content-Type: application/json" \ -d "{\"input_type\":\"base64\",\"input_data\":\"$BASE64_STR\"}" \ "https://v1.apizero.cn/api/food-license"请将
YOUR_API_KEY_HERE替换为你的真实API Key。若图片超过5MB会返回错误。
代码封装:Python示例
在实际工程中,推荐使用编程语言封装请求,方便错误处理和批量调用。以下使用Pythonrequests库实现:
import requests import json API_URL = "https://v1.apizero.cn/api/food-license" API_KEY = "YOUR_API_KEY_HERE" def recognize_food_license(image_data, input_type="url"): """ 识别食品经营许可证 :param image_data: 图片URL或Base64字符串 :param input_type: "url" 或 "base64" :return: 解析后的dict,含code和data """ headers = { "Content-Type": "application/json", "X-API-Key": API_KEY } payload = { "input_type": input_type, "input_data": image_data } try: resp = requests.post(API_URL, headers=headers, json=payload, timeout=30) resp.raise_for_status() # 非2xx状态码会抛出异常 result = resp.json() return result except requests.exceptions.RequestException as e: print(f"请求异常: {e}") return None except json.JSONDecodeError: print("响应非JSON格式") return None # 使用示例:通过URL识别 if __name__ == "__main__": url = "https://example.com/images/license.jpg" response = recognize_food_license(url, input_type="url") if response and response.get("code") == 0: data = response["data"] print("识别成功,字段如下:") for k, v in data.items(): print(f" {k}: {v}") else: msg = response.get("message", "识别失败") if response else "无响应" print(f"错误: {msg}")若使用Base64,只需将
input_type改为"base64",image_data传Base64字符串即可。注意requests.post(json=payload)会自动序列化字典。
返回值逐字段解读
成功返回HTTP状态码200,Body为JSON格式:
{ "code": 0, "data": { "complaints_hotline": "12315", "daily_supervisor": "王五", "daily_supervisory_authorities": "北京市朝阳区市场监督管理局", "domicile": "北京市朝阳区某街道1号", "issuer": "李四", "issuing_authority": "北京市朝阳区市场监督管理局", "legal_representative": "张三", "license_number": "JY14012800001234", "main_body": "餐饮服务经营者", "operating_item": "热食类食品制售", "operator": "某某餐饮有限公司", "premise": "北京市朝阳区某街道1号", "validity_period": "长期" }, "message": "success" }| 字段名 | 类型 | 说明 |
|---|---|---|
| license_number | string | 许可证编号 |
| operator | string | 经营者名称 |
| legal_representative | string | 法定代表人 |
| premise | string | 经营场所 |
| domicile | string | 住所(与经营场所可能相同) |
| main_body | string | 主体业态(如餐饮服务经营者) |
| operating_item | string | 经营项目(如热食类食品制售) |
| validity_period | string | 有效期(如“长期”或具体日期) |
| daily_supervisor | string | 日常监督管理人员 |
| daily_supervisory_authorities | string | 日常监督管理机构 |
| issuer | string | 发证人 |
| issuing_authority | string | 发证机关 |
| complaints_hotline | string | 投诉举报电话 |
注意:部分字段如daily_supervisor、issuer可能为空,取决于图片中是否包含这些信息。实际使用时建议对必填字段做非空校验。
错误码与常见问题
code字段不为0时表示异常,此时message包含原因简述。常见错误码:
| code | 含义 | 常见原因 |
|---|---|---|
| -1 | 系统错误 | 服务器内部异常,可稍后重试 |
| 400 | 请求参数错误 | 缺少必填字段、input_type非法、图片数据格式错误 |
| 401 | 鉴权失败 | API Key无效、过期或未提供 |
| 413 | 请求实体过大 | Base64图片超过5MB限制 |
| 415 | 不支持的媒体类型 | Content-Type不是application/json |
| 429 | 请求频率超限 | 超过QPS 2次/秒,需降速或加入重试退避 |
| 1001 | 图片识别失败 | 图片模糊、非食品经营许可证、文字遮挡等 |
排查思路
- 401错误:检查API Key是否正确,是否在Header中已传递。
- 400错误:检查
input_type是否拼写正确,input_data是否为空字符串。 - 413错误:Base64字符串长度是否过长,确认原始图片小于5MB。
- 1001错误:更换更清晰的图片;确保图片包含完整的证照正面;扫描件比手机拍照更稳定。
- 429错误:在代码中加入指数退避重试逻辑,或使用消息队列缓冲请求。
工程化注意事项
1. 鉴权方式统一
推荐统一使用X-API-Key请求头传递密钥,避免因请求体中的key字段被遗漏导致鉴权失败。在生产环境中,应将API Key存储在环境变量或密钥管理服务中,不要硬编码。
2. 图片预处理
- 图像分辨率建议不低于300dpi,JPEG/PNG格式均可。
- 若使用Base64,注意原始图片大小≤5MB。可通过压缩图片、降低分辨率来减小体积。
- 对非90°旋转的图片,可先旋转校正再传入,有助于提升识别成功率。
3. 频率控制与重试
由于QPS为2,若并发场景较高,建议使用令牌桶或请求队列控制速率。对于超时或5xx错误,可实现指数退避重试(例如重试3次,间隔1s、2s、4s)。
4. 字段校验与业务逻辑
返回的data中某些字段可能为空字符串,提取后应与数据库已有数据做比对,或触发人工复核流程。例如validity_period字段如果是“长期”,需要额外处理。
5. 日志与监控
记录每个请求的响应状态码、识别耗时、返回字段是否完整,便于发现接口异常或图片质量问题。
参考文档
- 食品经营许可证识别API文档:https://apizero.cn/aidocs/food-license
- 原始Markdown文档:https://apizero.cn/aidocs/food-license/raw.md