OCR图片空运价格提取
适用场景
用户提供空运价格图片(微信截图、报价单照片等),需要提取为24列标准Excel格式。
工具链
- OCR引擎:
rapidocr-onnxruntime - Python路径:
/c/Users/Administrator/AppData/Local/Microsoft/WindowsApps/python3.12.exe(系统Python 3.12,非managed Python) - 输出引擎:
pandas + openpyxl
OCR统一导入
推荐使用 ~/.workbuddy/skills/ocr_utils.py 统一OCR模块,跨平台一致。
工作流程
步骤1:复制图片到项目目录
cp "<微信临时路径>" "E:/FCI-RATE/0709_price_source_XXX.png"
步骤2:OCR识别(含坐标)
from rapidocr_onnxruntime import RapidOCR
engine = RapidOCR()
result, elapse = engine('图片路径')
# result: [bbox, text, confidence]
# bbox = [[x1,y1],[x2,y2],[x3,y3],[x4,y4]]
步骤3:表格结构还原
按Y坐标分组(15px容差)→ 组内按X排序 → 得到行列结构:
sorted_results = sorted(result, key=lambda x: (round(x[0][0][1]/15), x[0][0][0]))
# 按Y分组,每组内按X排序
步骤4:人工确认数据
OCR可能误识别,需人工核对:
- 价格数字(小数点、位数)
- 比重标签(全角/半角冒号混用:1: vs 1:)
- 中文词汇("以下"/"以上"/"托盘"/"散货"/"重货")
- 备注文本(可能被截断跨行)
步骤5:硬编码生成Excel
在 .workbuddy/tools/extract_<航司>_<目的港>.py 中硬编码确认后的数据。
24列标准格式
起始港|目的港|航司|开始比重|结束比重|货型|45KG|100KG|300KG|500KG|1000KG|散托类型|开始生效日期|分泡|频次|Remark|跳转点|转运点|转运费增量值(RMB/KG)|转运费最低收费(/票)|备注|来源|价格编号|散托增量
提取规则
全局规则
- 频次为空时默认填"Daily":频次列如果为空则填入 Daily(0727全局规则)
- 分泡列不提取:分泡列始终留空,不提取任何分泡数据(0720全局规则)
货型字段
- 去掉所有中文:
1:100以下→1:100,1:150以上→1:150,1:167托盘→1:167,1:400重货→1:400 - 统一半角冒号:
1:80→1:80
比重区间(链式推导)
- 首行 start=0
- 每行 end = 下一行的比重阈值
- 末行 end=9999
- "以下"行:end=当前阈值,start=0(或上一行end)
- "以上"行:start=当前阈值,end=下一行阈值
散货/托盘处理
- 同一比重行含散货价和托盘价 → 拆为两行(散货一行,托盘一行)
- 货型标签含"托盘"→散托类型=托盘
- 货型标签含"散货"→散托类型=散货
- 货型标签含"重货"或无标注→散托类型=散货/托盘
- 散托增量有值时,散托类型统一改为"散货"
价格处理
- "单询"→不提取(价格留空None)
- 全空价格行(45K-1000K都为空)→不提取
- 只有45K有值,其他为单询→提取(45K有值即可)
目的港/生效日期识别
- 从OCR文本中查找三字代码(如FRA、AMS、LAX等)
- 从"X月X号"或"X/X起"格式提取生效日期
- 示例:"FRA7/12起2吨以上请单询"→目的港=FRA,生效日期=2026-07-12
输出顺序
- 按源文件图片中的行顺序输出,不排序(便于人工核对)
脚本模板
# 配置
ORIGIN = "PVG"
DEST = "<目的港>"
CARRIER = "<航司>"
SOURCE = "<来源>"
PRICE_ID = "<价格编号>"
EFF_DATE = "<生效日期>"
FREQ = "DAILY"
# raw_data: (start_w, end_w, cargo_type, p45, p100, p300, p500, p1000, san_type, remark, san_inc)
raw_data = [
# 每行按OCR确认的数据硬编码
]
# 过滤全空价格行
# 散托增量有值→散托类型改为散货
# 散托类型默认→散货/托盘
# 输出到 0701/ 目录
已完成案例
| 案例 | 航司 | 路线 | 行数 | 价格编号 | 日期 |
|---|---|---|---|---|---|
| CZ/CA/CK-AMS | CZ/CA/CK | PVG→AMS | 14 | CZ_CA_CK_001 | 2026-07-11 |
| CZ/CA/CK-FRA | CZ/CA/CK | PVG→FRA | 16 | CZ_CA_CK_002 | 2026-07-12 |
| MU-EZE | MU | PVG→AKL→EZE | 8 | MU-EZE_001 | 2026-04-06 |
常见OCR陷阱
- 全角冒号:
1:常被识别,需统一为半角1: - 跨行文本:备注可能被OCR拆成两行(如"FRA7/12起2吨以"+"上请单询"),需合并
- 价格偏移:某些价格可能被识别到相邻列的位置,需对照X坐标确认所属列
- 数字混淆:
0和O、1和l、5和S等,需结合上下文判断 - 散货/托盘混合行:如"散货20(8CB以内19)"+"托24(500KG以内23)"在同一行,需拆为两行输出