最小可运行示例:用火车票识别API提取13个票据字段
最小可运行示例:火车票识别API实战
在开发票据自动录入、差旅报销、行程管理等功能时,OCR识别是绕不开的一环。本文聚焦于一个具体的、可直接运行的API——火车票识别。我们不谈理论,只给代码和参数,让你复制后修改API Key就能跑起来。
适用场景
- 差旅费报销自动录入:财务人员上传员工火车票照片,系统自动提取出发/到达站、票价、身份证号等字段,直接填入报销单,减少人工录入错误。
- 行程管理与核验:企业内部OA系统对接API,自动扫描上传的火车票图片,校验车次、时间与出差申请是否匹配。
- 票据归档与搜索:对历史火车票进行数字化归档,支持按车次、站点、金额等字段检索。
接口能力边界
该API支持国内主流全类型火车票(高铁、动车、普通车票),输出13个结构化字段,包括:出发站、到达站、车次、乘车人姓名、座位类别、座位号、票价(含大写金额)、出发时间、身份证号、售卖站、票号、订单号、座位等级等。核心能力如下:
- 单次请求处理一张火车票图片(URL或Base64均可)。
- 最大QPS:2次/秒(调用频率超过此限制将返回限流错误)。
- 仅限已登录用户调用,请求头中必须携带有效API Key。
- 返回内容包含敏感信息(姓名、身份证号),请务必在安全环境下传输并妥善存储。
准备工作:获取API Key
- 访问文档页并准备登录(步骤略,以API平台实际流程为准)。
- 在个人控制台创建应用并生成API Key。
- 记住Key值,调用时会放在请求头的
Authorization字段中,格式为Bearer <你的API Key>。
请求参数详解
接口地址:POST https://v1.apizero.cn/api/ocr-train-ticket
Header参数
| 参数名 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
| Authorization | 是 | string | 认证凭据,格式:Bearer sk-xxxxxxxx |
| Content-Type | 否 | string | 请求体格式,默认application/json |
请求体(JSON)
| 字段名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| input_type | string | 是 | 图片传输方式,可选url或base64 | "url" |
| input_data | string | 是 | 图片内容:URL时填公网可访问的图片链接;base64时填图片Base64编码字符串(可含data:image/xxx;base64,前缀) | "https://example.com/ticket.jpg" |
注意:图片大小建议控制在5MB以内,过大图片易导致超时或返回500错误。
最小可运行示例:curl调用
以下curl命令是一个完整的可复制样例。你需要将YOUR_API_KEY替换为你自己的Key,并将input_data替换为你真实的火车票图片URL:
curl -sS -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"input_type": "url", "input_data": "https://example.com/train-ticket.jpg"}' \ "https://v1.apizero.cn/api/ocr-train-ticket"如果图片是本地Base64,可以先生成Base64字符串再传入(推荐使用工具base64命令或编程语言内置函数):
# Linux/Mac 下的Base64编码示例 BASE64=$(base64 -w0 /path/to/train-ticket.jpg) curl -sS -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"input_type\": \"base64\", \"input_data\": \"$BASE64\"}" \ "https://v1.apizero.cn/api/ocr-train-ticket"提示:在Windows PowerShell中,JSON内双引号需要转义为
\",或者使用-replace生成字符串。更推荐使用Python等编程语言构造请求。
Python代码接入(最小可运行示例)
以下Python脚本使用requests库,同样需要替换API Key和图片URL。代码中包含了完整的异常处理和响应打印:
import requests import json API_URL = "https://v1.apizero.cn/api/ocr-train-ticket" API_KEY = "YOUR_API_KEY" # 替换为你的Key def recognize_train_ticket(image_url): """ 通过URL识别火车票,返回解析结果字典。 """ headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "input_type": "url", "input_data": image_url } try: resp = requests.post(API_URL, headers=headers, json=payload, timeout=10) resp.raise_for_status() result = resp.json() if result.get("code") == 0: print("✅ 识别成功,数据如下:") print(json.dumps(result["data"], indent=2, ensure_ascii=False)) return result["data"] else: print(f"❌ 业务错误:{result.get('msg')}") return None except requests.exceptions.RequestException as e: print(f"❌ 网络或HTTP错误:{e}") return None except json.JSONDecodeError as e: print(f"❌ 响应非JSON格式:{e}") return None if __name__ == "__main__": # 测试一张可访问的火车票图片 test_url = "https://example.com/train-ticket.jpg" # 替换为真实图片 recognize_train_ticket(test_url)运行前请确保已安装requests:pip install requests
返回字段解读
成功时HTTP状态码200,响应体示例(JSON):
{ "code": 0, "data": { "start_station": "北京南", "end_station": "上海虹桥", "train_num": "G101", "name": "张三", "seat_cls": "二等座", "seat_num": "05车12A号", "price": "553.00", "total_amount": "¥553.00", "time": "2024-01-15 09:00", "id_num": "110101199001011234", "sale_num": "G123456", "sale_station": "北京南", "ticket_num": "E123456789" }, "msg": "成功", "request_id": "req_abc123" }各字段含义:
| 字段 | 类型 | 说明 |
|---|---|---|
| start_station | string | 出发站名称 |
| end_station | string | 到达站名称 |
| train_num | string | 车次号,如G101 |
| name | string | 乘车人姓名 |
| seat_cls | string | 座位等级,如二等座、一等座、硬卧等 |
| seat_num | string | 座位号,如05车12A号 |
| price | string | 票价数字,如553.00 |
| total_amount | string | 票价含¥符号,如¥553.00 |
| time | string | 出发时间,格式YYYY-MM-DD HH:MM |
| id_num | string | 乘车人身份证号(已脱敏?示例为全号,实际可能部分隐藏) |
| sale_num | string | 售票单号或订单号 |
| sale_station | string | 售票站名称 |
| ticket_num | string | 票号 |
| request_id | string | 本次请求的唯一标识,用于排查问题 |
说明:实际返回字段可能因图片质量、版面差异而略有不同。未识别到的字段将缺失,后端不会填充空字符串。建议调用方对缺失字段做容错处理。
常见错误与处理策略
| 场景 | HTTP状态码 | code字段 | msg字段 | 常见原因 | 解决方案 |
|---|---|---|---|---|---|
| 授权失败 | 401 | -1 | 认证失败 | API Key无效或过期 | 检查Authorization格式及Key有效性 |
| 参数错误 | 400 | 1001 | input_type不合法 | input_type不是url/base64 | 检查传值 |
| 图片无法访问 | 400 | 1002 | 图片下载失败 | 图片URL不可访问或超时 | 更换为公网可访问URL或转用Base64 |
| 图片类型不支持 | 400 | 1003 | 图片解析失败 | 图片可能不是火车票,或格式损坏 | 确保图片清晰,建议jpg/png,无过度压缩 |
| 限流 | 429 | -2 | 请求过快,请稍后重试 | 超过QPS限制(2次/秒) | 加入重试逻辑,增加退避 |
| 服务器内部错误 | 500 | -99 | 系统异常 | 后端异常 | 稍后重试,或联系技术支持 |
工程化建议:在代码中增加重试机制,对于429和5xx错误,采用指数退避重试(如等待1s、2s、4s后重试,最多3次)。
工程化注意事项
- 图片获取与预处理:手机拍照的火车票常出现反光、倾斜或褶皱,影响识别准确度。建议调用前使用图像处理库(如OpenCV)进行校正、增强对比度。不能保证100%完全正确字段,生产环境应加入人工复核环节。
- 敏感信息保护:响应中包含姓名和身份证号,传输时必须使用HTTPS;数据库存储时需加密,或根据业务需求脱敏输出(如只显示姓名的首位和身份证号的前后四位)。
- 并发控制:QPS限制2,如果你的系统需要处理多张票,应使用令牌桶或队列控制请求速率,避免频繁触发限流。
- Base64方案优于URL:当图片存储在内网或私有云时,直接传Base64可以避免URL鉴权问题,但Base64字符串较大,注意请求体大小限制(一般服务端限制为10MB以内)。建议先压缩图片再编码。
- 日志与监控:记录请求ID(request_id)和识别结果,便于追踪问题。定期统计失败率,超过阈值时报警。
参考文档
- API官方文档页:火车票识别接口说明
- 原始OpenAPI规范:raw.md
(本文仅展示技术操作,不包含任何用量说明、或商业引导信息。)
