Back to skills
extension
Category: Data & AnalyticsNo API key required

澳洲空运价格提取

AOZHOU 澳洲空运价格 OCR 提取规则。当用户提供澳洲价格图片(.png 格式)时使用。触发词:aozhou、澳洲、澳洲运价、AOZHOU。

personAuthor: user_17da570ahubcommunity

AOZHOU 价格提取 Skill

OCR 识别澳洲空运价格图片 → 24列标准输出 → 上传 WPS。

⚠️ 铁律:仅提取用户最新提交图片,禁止复制历史数据

  • 禁止查看/引用/复制任何历史脚本中的 price/data 数组
  • 禁止从历史输出文件直接读取数据
  • 禁止硬编码历史图片路径作为源文件
  • 每次提取必须从用户当前提交文件全新 OCR 识别
  • 有就是有,没有就是没有:不得用历史数据填补缺失值

一、核心参数

| 参数 | 值 | |------|-----| | 起始港 | PVG | | 价格编号 | aozhou_aozhou_001 | | 来源 | aozhou | | 引擎 | ocr_utils(跨平台统一 RapidOCR 封装,~/.workbuddy/skills/ocr_utils.py) | | 输入格式 | PNG 图片 | | 45KG | 有值(图片含45KG列) |


二、强制流程

1. 确认图片路径
2. ocr_utils.scan_to_log() 扫描 → 日志输出
3. 按 Y 坐标分组识别数据块
4. ocr_utils.find_price_at_xy() 逐行提取 → 比重推导
5. 生成 24 列 DataFrame
6. 保存 → 上传 WPS → 删除临时文件

2.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()  # 启动时自检,确保引擎版本一致

三、目的地数据块配置 ⚠️ 最可能变化

3.1 生效日期(每个目的地不同)

| 目的地 | 生效日期 | 航司 | 频次 | |--------|---------|------|------| | AKL | 2026-04-24 | MU | Daily | | BNE | 2026-04-18 | MU | D24567 | | MEL | 2026-04-23 | MU/HO | Daily/D246 | | SYD | 2026-04-15 | MU/HO | Daily/D1357 |

3.2 备注(每个目的地不同)

| 目的地 | 备注 | |--------|------| | AKL | MUSTGO +5, 比重价格需要满300KG起 | | BNE | MUST GO +5, 比重价格需要满300KG起 | | MEL | 指定航司+2, 托书请备注有无电池, MUST GO运价+5 | | SYD | 指定航司+2, 托书请备注有无电池, MUST GO运价+5 |


四、OCR 坐标提取(核心)

4.1 价格列 X 坐标范围

| 重量段 | AKL X范围 | BNE X范围 | MEL X范围 | SYD X范围 | |--------|-----------|-----------|-----------|-----------| | 45KG | 320-340 | 335-345 | 330-345 | 330-345 | | 100KG | 460-480 | 460-475 | 460-475 | 460-475 | | 300KG | 555-565 | 550-560 | 550-560 | 645-660 | | 500KG | 650-660 | 645-655 | 645-655 | 720-730 | | 1000KG | 745-760 | 745-755 | 745-755 | 860-875 |

⚠️ 新图片 X 范围可能变化:需要对照图片重新标定。

4.2 数据行 Y 坐标(每个目的地)

AKL(4 行,Y=180-520)

209 平托 → 托盘, 238 平散 → 散货, 268 1:120以下散 → 散货
300 1:100以下散 → 散货, 331 1:300托盘 → 托盘, 360 1:300散货 → 散货
387 1:500托盘 → 托盘, 420 1:500散货 → 散货, 450 1:800托盘 → 托盘
480 1:800散货 → 散货, 511 1:1000散托 → 散货/托盘

BNE(3 行,Y=697-980)

742 平托 → 托盘, 778 平散 → 散货, 811 1:120以内泡散 → 散货
865 1:100以内泡散 → 散货, 917 1:300散托 → 散货/托盘
949 1:500散托 → 散货/托盘, 977 1:800散托 → 散货/托盘

MEL(2 行,Y=1227-1700)

1305 平托 → 托盘, 1374 平散 → 散货, 1442 1:100以内限散 → 散货
1506 1:250散 → 散货, 1572 1:300托 → 托盘, 1637 1:300散 → 散货
1698 1:500散+托 → 散货/托盘

SYD(3 行,Y=1954-2380)

2016 平托 → 托盘, 2061 平散 → 散货, 2107 1:100以内限散 → 散货
2140 1:250散 → 散货, 2199 1:300托 → 托盘, 2241 1:300散 → 散货
2287 1:400散+托 → 散货/托盘, 2333 1:500散+托 → 散货/托盘
2378 1:800散+托 → 散货/托盘

⚠️ 新图片 Y 坐标必须重新标定:用 OCR 日志对齐文本。


五、货型清理规则

def clean_cargo_type(cargo_str):
    cargo_str = cargo_str.replace(':', ':').replace(' ', '')
    # 平托/平散 → 1:1
    if '平托' in cargo_str or '平散' in cargo_str:
        return '1:1'
    # 1:XXX格式 → 保留
    match = re.search(r'1:(\d+)', cargo_str)
    if match:
        return f"1:{match.group(1)}"
    return cargo_str

最终货型格式:1:11:1001:1201:2501:3001:4001:5001:8001:1000


六、比重推导(calc_ratio_range

与 Excel 数据源不同,AOZHOU 使用自定义推导(非 ratio_engine):

# 正常 1:XXX → start=XXX, end=下一个更大比的start-1
# "1:XXX以下/以内/限" → start=0, end=XXX
# 末档 → end=9999

关键规则:相同比重的多行(如 1:300 托盘 + 1:300 散货)共享同一结束比重


七、散托类型判断

| 条件 | 散托类型 | |------|---------| | cargo_str 含「托」(且不是散货/托盘)| 托盘 | | st_type 是「散货/托盘」| 散货/托盘 | | 其他 | 散货 |

⚠️ 优先级:cargo_str 判断 > st_type 默认值。


八、价格提取(find_price_at_xy

def find_price_at_xy(target_ys, x_min, x_max):
    # Y 容差 ±5 像素
    # X 必须在 x_min ~ x_max 范围内
    # 匹配纯数字(含小数)
    # 返回 float
  • 支持 target_ys 为 list(多行范围)
  • 正则:^\d+(\.\d+)?$

九、常见坑

坑1:X 坐标偏移

新图片排版不同时,价格列 X 范围需要重新标定。对照 OCR 日志逐列验证。

坑2:Y 坐标漂移

OCR 对同一图片的 Y 坐标可能有 ±3px 偏差,abs(y - target_y) <= 5 容差处理。

坑3:1000KG 可能在下一行

AKL 1000KG 搜索范围扩大到了 [y-2, y+3]

坑4:BNE 1000KG OCR 异常

OCR 可能误读价格,需检查 1000KG > 100KG 时用 100KG 值替换。

坑5:int() 转换丢失小数

价格直接用 int() 而非 float,注意检查是否有小数价格。

🔴 坑6:凭记忆看图片 → 复制历史数据(0608惨痛教训)

错误:AKL/BNE/MEL/SYD 四个已有航线的价格,实际输出的是旧批次数据,而非 0608 图片数据。

  • AKL-MU 平托:应该 32/30/30/30/30,输出成了旧数据的 32/20/19/17/17
  • SYD-MU 1:300托:应该 32/32/32,输出成了旧数据的 37/37/37
  • BNE 列格式:新图片是标准5列(45/100/300/500/1000),旧脚本是非标准列(100/500/1000)

铁律

  1. ❌ 禁止"扫一眼图片"就标记为熟悉航线,凭记忆填数据
  2. 必须逐行跑 RapidOCR,逐格对照 OCR 日志填入数据
  3. ✅ 即使是"已有航线",也必须基于当前图片 OCR 录入
  4. ✅ ZRH/ARN/CAI 新航线数据正确,恰恰证明了「新航线 = 强制看图片 = 不出错」

🔴 坑7:OCR Y坐标段归属串位(0608教训)

错误:OCR Y=2346 的 1:800散+托=24/24 属于 MEL 段,但被错误复制到 SYD 段。 SYD 段实际末行为 Y=3315 1:500散+托=29/29/29,图中无 1:800。

铁律:每条航线提取完成后,必须回看图片确认首行和末行的货型是否正确,防止 OCR 坐标串位。

坑8:MUSTGO +5 ≠ 散托增量(0608教训)

错误:将 MUSTGO +5 / MUST GO +5 当作散托增量(散托增量=5)。 MUSTGO 是优先货物附加费,不是托盘加价

铁律:AOZHOU 图片中 没有散托增量(无「托盘+N元/kg」字样),散托增量列全部留空。

坑9:卡车转运段不提取(0608教训)

错误:提取了「BNE/ADL/PER 中转统配 JL/HO/TG/PR」和「SYD/MEL 中转统配 NH/JL/TG/5J/AI/PR」。 这些都是 卡车转运/地面运输价格,非空运报价,不应提取。

铁律:图片中含「中转」「统配」「卡车点」等字样的段落 → 跳过不提取

坑10:OCR 未捕获货型标签时禁止猜测(0608教训)

错误:CK-AKL 首行 OCR 未捕获货型标签(Y=604 仅有数字 40/33/33/33/33),猜测填「散托」。 实际应为「平托→1:1」。

铁律:OCR 缺失货型标签时,对照图片人工确认,不能凭价格高低推测货型。

坑11:图片中斜杠(/)价格不得补填(0608教训)

错误:MEL 1:800 图片中 300KG 列为斜杠(/),脚本中填入了 24。 1:800 比率下 300KG 不在报价范围,应为空。

铁律:图片标注「/」的格子 → 输出留空,禁止用相邻列价格补填。

坑12:全段同价货物不拆分比率(0608教训)

错误:早期将「平托」一行拆分成多个比率段(1:1→1:100→1:200→...),产生重复数据。

铁律:平托/平散/单机 等全段同价货物 → 单行输出,范围 0→9999,货型 1:1。

#11 ZRH/ARN(MU)

| 项目 | 值 | |------|-----| | 源文件 | 用户提交 | | 生效日期 | 从图片标题提取;0618 图片中 ZRH 为 2026-06-18,ARN 为 2026-06-22 | | 价格编号 | aozhou_aozhou_001 | | 航司 | MU | | 提取范围 | 仅提取 ZRH/ARN 主运价区;下方 卡车点 转运费表不提取 | | ZRH | 45KG 全空;频次 D247;备注 6.18首航, 不能锂电池/不分泡, MUSTGO +5, 不可锂电池 | | ARN | 45KG 全空;频次 D146;备注 6.22首航, 不能锂电池, 5/5分泡, 大盘底泡托盘不接, MUST GO +5 | | 行数 | ZRH 9 行、ARN 7 行;仅按图片主运价逐行输出,不展开卡车点 | | 比重 | 平托/平散为 1:1(0-9999)1:100内1:80内1:120内0-XXX;普通链式档按图片实际档位到下一档,末档到 9999 | | 散托类型 | 按图片标签保留托盘/散货/散货/托盘;MUSTGO +5 只写备注,不写散托增量 |


十、脚本模板

脚本模板:/Users/hantao/WorkBuddy/oone/extract_aozhou.py 图片:用户提交(可通过命令行参数指定)

新图片时需更新:

  1. 所有目的地的 OCR 数据 → 手动录入 data 数组
  2. 生效日期(对应图片标题日期)
  3. 备注信息(MUSTGO 仅放备注列)
  4. 确认无卡车转运段数据
  5. 确认散托增量全部为空
  6. 逐像素核对 OCR 数据与图片一致
  7. 0615 这类长图可按主运价分段处理:AKL、BNE、ADL、MEL、SYD;中间的“中转统配/卡车点”整段跳过
  8. 目的港、备注、航司只取主运价区;不要把中转统配段混入主表