Goldjet 价格提取 Skill
OCR 识别 Goldjet 欧洲航线价格图片(MXP/BCN/MAD)→ 24列标准输出 → 上传 WPS。
⚠️ 铁律:仅提取用户最新提交图片,禁止复制历史数据
- 禁止查看/引用/复制任何历史脚本中的 price/data 数组
- 禁止从历史输出文件直接读取数据
- 禁止硬编码历史图片路径作为源文件
- 每次提取必须从用户当前提交图片全新 OCR 识别
- 有就是有,没有就是没有:不得用历史数据填补缺失值
一、核心参数
| 参数 | 值 |
|------|-----|
| 起始港 | PVG |
| 价格编号 | BCN/MAD/MXP: goldjet_mxpbcnmad_001;CDG: goldjet_cdg_001 |
| 来源 | GOLDJET |
| 引擎 | ocr_utils(跨平台统一 RapidOCR 封装,~/.workbuddy/skills/ocr_utils.py) |
| 输入格式 | JPG/PNG 图片 |
| >XXX 货型 | 按项目规则统一改为 1:XXX(如 >200 → 1:200),比重区间仍按图片实际链式推导 |
二、航线概览(4条)
| 目的地 | 航司 | 生效日期 | 频次 | 价格结构 | |--------|------|---------|------|---------| | MXP | CA/MU | 图片标题提取 | Daily | 标准 5 列价格(45/100/300/500/1000) | | BCN | CA/MU | 图片标题提取 | D1246 | 标准 5 列价格 | | MAD | CA/MU(历史批次 MU) | 图片标题提取 | Daily | 因批次而异:0525 为双列(散货+托盘),0601 为单列 | | CDG 🆕 | 2C/IU | 图片标题提取 | 空 | 无45KG列(仅100/300/500/1000),散托分行 |
三、强制流程
1. 确认图片路径(.jpg)
2. ocr_utils.scan_to_log() 扫描全图
3. 按 Y 坐标识别航线区域(MXP → BCN → MAD,或仅 CDG)
4. ocr_utils.find_price_at_xy() / find_text_at_xy() 提取 + 备注解析
5. 生成 24 列 DataFrame
6. 保存 → 上传 WPS
3.1 OCR 统一导入(所有平台一致)
import sys, os
sys.path.insert(0, os.path.expanduser('~/.workbuddy/skills'))
from ocr_utils import scan_image, scan_to_log, find_price_at_xy, find_text_at_xy, check_env
check_env() # 启动时自检,确保引擎版本一致
四、OCR 坐标(核心规则)⚠️ 新图片必须重新标定
4.1 价格列 X 坐标
X_COLS = {
'45': (270, 310),
'100': (335, 375),
'300': (395, 440),
'500': (455, 500),
'1000': (515, 560),
}
X_REMARK = (570, 700) # 备注列
4.2 MXP 区域(Y=0~220)
🔧 每个批次按 OCR 日志重新标定。0525批次货型全部为 1:XXX(无 >XXX)。
# 0525参考坐标: (cargo_y, 货型, 开始比重, 结束比重)
mxp_rows_0525 = [
(44, '1:100', 0, 100),
(64, '1:120', 100, 120),
(84, '1:167', 120, 167),
(104, '1:200', 167, 200),
(124, '1:250', 200, 250),
(144, '1:300', 250, 300),
(164, '1:500', 300, 500),
(184, '1:800', 500, 800),
(204, '1:1000', 800, 9999),
]
比重规则(当前批次):
- 全部 1:XXX 格式,链式推导:end = 下档 start,末档=9999
4.3 BCN 区域(Y=220~490)
🔧 每个批次按 OCR 日志重新标定。0525批次货型全部为 1:XXX。
# 0525参考坐标: (cargo_y, 货型, 开始比重, 结束比重)
bcn_rows_0525 = [
(264, '1:100', 0, 100),
(283, '1:120', 100, 120),
(304, '1:167', 120, 167),
(324, '1:200', 167, 200),
(344, '1:250', 200, 250),
(364, '1:300', 250, 300),
(384, '1:500', 300, 500), # 备注空=托散同价
(404, '1:800', 500, 800),
(424, '1:1000', 800, 9999),
]
4.4 MAD 区域(Y=490+)⚠️ 双列特殊格式
MAD 与 MXP/BCN 完全不同:只有两列(散货 + 托盘),每列一个价格填入全部 5 个重量段。
X_MAD_LOOSE = (275, 295) # 散货列 OCR 坐标
X_MAD_PALLET = (346, 366) # 托盘列 OCR 坐标
mad_rows = [
(493, '1:80', 0, 80), (512, '1:100', 80, 100),
(533, '1:120', 100, 120), (553, '1:167', 120, 167),
(572, '1:200', 167, 200), (592, '1:250', 200, 250),
(612, '1:300', 250, 300), (633, '1:500', 300, 500),
(653, '1:800', 500, 800), (673, '1:1000', 800, 9999),
]
每个比重行产出两条记录:散货记录 + 托盘记录,价格分别从对应 OCR 列提取,相同的值填充到 45/100/300/500/1000KG。
4.5 CDG 航线 🆕 0601新增(2C/IU统配)
格式特征:
- 无 45KG 列,仅 100K/300K/500K/1000K 四列
- 散货/托盘分行(非分列):1:200~1:300 每档两条(散+托各一行)
- 前两档(1:140, >140)散货行标注托盘+2 增量
- 航司: 2C/IU(非 CA/MU)
# 0601 参考数据(手动录入)
cdg_rows_0601 = [
# 货型, start, end, 100K,300K,500K,1000K, st_type, inc, remark
('1:140', 0, 140, 35, 35, 35, 35, '散货', '2', '托盘+2'),
('>140', 140, 200, 36, 36, 36, 36, '散货', '2', '托盘+2'),
('1:200', 200, 250, 38, 38, 38, 38, '托盘', '', ''),
('1:200', 200, 250, 36, 36, 36, 36, '散货', '', ''),
('1:250', 250, 300, 37, 37, 37, 37, '托盘', '', ''),
('1:250', 250, 300, 35, 35, 35, 35, '散货', '', ''),
('1:300', 300, 500, 36, 36, 36, 36, '托盘', '', ''),
('1:300', 300, 500, 34, 34, 34, 34, '散货', '', ''),
('1:500', 500, 800, 34, 34, 34, 34, '散货/托盘', '', ''),
('1:800', 800, 1000, 33, 33, 33, 33, '散货/托盘', '', ''),
('1:1000', 1000, 9999, 32, 32, 32, 32, '散货/托盘', '', ''),
]
比重规则:链式推导,散货和托盘同行号时结束比重相同(如 1:200 散=200-250, 1:200 托=200-250)。
触发识别:当图片列头仅含 100K/300K/500K/1000K(无 45KG),且航司为 2C/IU 时,即 CDG 航线。
五、价格提取函数(find_text_at_xy)
def find_text_at_xy(target_ys, x_min, x_max):
# Y 容差 ±4 像素
# X 必须在 x_min ~ x_max 范围内
# 正则匹配纯数字 ^\d+(\.\d+)?$
# 返回 float
六、散托类型与增量
def parse_tray_increment(remark):
# 正则: r'托盘\+(\d+)'
# 匹配格式: "托盘+2MU-2" → 增量=2
# 无匹配 → None
规则:
- 备注有「托盘+N」→ 散货,增量=N
- 备注空或无托盘 → 散货/托盘,增量=''
- BCN 后 3 行备注为空 → 托散同价(散货/托盘)
七、价格过滤
所有 5 个重量段全为 None 的行不提取。
八、货型规则
| 原始格式 | 最终格式 | 说明 |
|---------|---------|------|
| 1:100 | 1:100 | 保留 |
| >200 | 1:200 | 按项目规则统一转为 1:XXX |
⚠️ Goldjet 货型以当前图片为准;若 OCR 读到 >XXX,输出仍统一改为 1:XXX。
九、价格小数保留
Goldjet 价格必须保留图片原始小数,禁止 int() 转换;例如 48.00 可写为数值 48,12.50 必须保留为 12.5。
九点一、0615 MXP 单图规则
| 项目 | 值 |
|------|-----|
| 源文件 | 用户提交 |
| 生效日期 | 图片下方标题提取;0615 批次为 2026-06-17 |
| 价格编号 | goldjet_mxpbcnmad_001 |
| 航司 | 图片标题 CA/CP/MU-浦东直飞MXP货机航班,输出 CA/CP/MU |
| 目的港 | 主运价目的港为 MXP;下方卡车中转表不提取 |
| 主运价行 | MXP 行输出 1:1(0-100);1:100-120 输出 1:100(100-120);1:120-167平货 输出 1:167(120-167);1:200重货 输出 1:200(167-200);1:250/300/500/800 按图片链式输出;1:1000重货 全价格为空不提取 |
| 托盘增量 | 备注有 托盘+N → 散托类型=散货、散托增量=N;备注为空 → 散货/托盘 |
| 中转费 | 不提取;图片下方卡车中转费用、仓位/价格、minimum 等均不进入 24 列输出 |
| 注意 | 图片列头重复显示 100K,按标准列顺序映射为 100/300/500/1000KG;价格列保留小数 |
九点二、0615 BCN/MAD 单图规则
| 项目 | 值 |
|------|-----|
| 源文件 | 用户提交 |
| 生效日期 | 图片下方标题提取;0615 批次为 2026-06-18 |
| 价格编号 | goldjet_mxpbcnmad_001 |
| 航司 | 图片标题 CA/MU-浦东直飞BCN航班、CA/MU-浦东直飞MAD航班,输出 CA/MU |
| 目的港 | 上方主运价分别输出 BCN、MAD;下方卡车中转表不提取 |
| 主运价行 | 1:100以下 输出 1:1(0-100);1:110 输出 1:110(100-130);1:130-167平货 输出 1:167(130-167);1:200重货 输出 1:200(167-250);1:250/300/500/800 按图片链式输出,末档 1:800(800-9999) |
| 45KG | BCN 前 3 行有 45KG=53;BCN 1:200 起和 MAD 全部 45KG 留空 |
| 托盘增量 | 前 5 行备注 托盘+2 → 散托类型=散货、散托增量=2;后 3 行备注为空 → 散货/托盘 |
| 中转费 | 不提取;图片下方卡车中转费用、仓位/价格、minimum 等均不进入 24 列输出 |
十、常见坑
坑1:MAD 双列格式特殊性
MAD 不按 5 列提取,而是散货列 + 托盘列各读一个值,填满 5 个重量段。
坑2:BCN 备注空 → 托散同价
后 3 行备注为空,散托类型应设为「散货/托盘」而非 None。
坑3:>XXX / 1:XXX 格式按实际图片决定(0525更新)
Goldjet 格式因批次而异。0525批次全部为 1:XXX,无 >XXX。以 OCR 实际读到为准,不要强制转换。
坑4:价格行 Y 偏移
每个 cargo 行的价格不在同一 Y,有 price_y_offset 偏移(如 MXP 1:100 价格在 Y+3)。
坑5:int() 可能丢失小数
OCR 有时读到 12.50,int() 会截断为 12。需确认是否需要 float。
坑6:MAD 结构可能变回单列 🔴 0601批次
症状:0525 中 MAD 是双列(散货+托盘分开),0601 变回单列(同 BCN 格式,托盘+2 备注)。 规则:每个批次必须以 OCR 实际为准判断 MAD 格式,不预设。
坑7:航线可能不完整 🔴 0601批次
症状:0601 图片仅含 BCN+MAD,无 MXP。不要机械生成三条航线。 规则:以 OCR 识别的航线标题数量为准。
坑8:货型标签可能含范围/描述 🔴 0601批次
症状:0601 货型出现 1:110-130、1:130-167平货、1:200重货 等新格式,不再是纯 1:XXX。
规则:提取纯比重数字作为 cargo_type(如 1:110-130→1:130),比重范围按链式推导。
坑9:45KG 可能部分为空 🔴 0601批次
症状:0601 BCN 仅前 3 行有 45KG(53),1:200 起全部为空。MAD 全线无 45KG。 规则:按 OCR 实际值,空即为空,不要填入占位值。
坑10:CDG 新航线 - 无 45KG 列 🔴 0601新增
症状:CDG 航线列头不含 45KG,如果按标准 5 列坐标提取会导致错位。 规则:识别列头关键词,无 45KG 时仅处理 4 列(100/300/500/1000),45KG 列留空。
坑11:CDG 新航线 - 散托分行 >140 货型 🔴 0601新增
症状:货型标签含「1:140以上」、「1:100-1:140」等中文范围描述,需要转换为 >140 标准格式。
规则:1:100-1:140 → 货型=1:140,1:140以上 → 货型=>140。
坑12:CDG 新航线 - 航司非 CA/MU 🔴 0601新增
症状:CDG 航司是 2C/IU,非 MXP/BCN/MAD 的 CA/MU。 规则:不要用 MXP/BCN/MAD 的航司常数值,每次按图片实际标题提取。
坑13:卡车转运费用不提取(0615新增)
Goldjet 图片下方常带卡车中转表(minimum、每 KG 转运费、仓位/价格等)。用户确认这些卡车转运费用不必提取,输出仅保留主运价行,转运点/转运费列留空。
十一、脚本模板
脚本模板:/Users/hantao/WorkBuddy/oone/extract_goldjet_mxpbcnmad.py
图片:用户提交
新图片时需重新标定:
- 价格列 X 坐标(5列 + 备注列)
- MAD 双列 X 坐标
- 各航线行的 Y 坐标 + price_y_offset
- 生效日期(对应图片日期)
- 运行 → 验证 → 上传 WPS
微信扫一扫