CIMC 价格提取 Skill
提取 CIMC(广州/深圳)空运运价表 → 24列标准输出 → 上传 WPS。
⚠️ 铁律:仅提取用户最新提交文件,禁止复制历史数据
- 禁止查看/引用/复制任何历史脚本中的 price/data 数组
- 禁止从历史输出文件直接读取数据
- 禁止硬编码历史文件路径作为源文件
- 每次提取必须从用户当前提交文件全新读取
- 有就是有,没有就是没有:不得用历史数据填补缺失值
一、核心参数(固定不变)
广州
| 参数 | 值 |
|------|-----|
| 起始港 | CAN |
| 价格编号 | cimc_can_001(QR货机 cimc_can_qrfreighter_001,QR联运 cimc_can_qrjoint_001) |
| 来源 | CIMC |
| 文件类型 | .xls(xlrd 读取) |
深圳
| 参数 | 值 |
|------|-----|
| 起始港 | SZX |
| 价格编号 | cimc_szx_001 |
| 来源 | CIMC |
| 文件类型 | .xls(xlrd 读取) |
二、强制流程(铁律)
1. 确定源文件路径(广州 .xls / 深圳 .xls)
2. 确定基准日期 BASE_DATE(如 "2026-05-18")
3. 加载 Skill 规则 → 运行提取脚本
4. 比重引擎处理(apply_ratio_engine)
5. 24列校验 → 保存 Excel → 自动上传 WPS
三、广州 Sheet 配置(16 个 Sheet)⚠️ 最可能变化
3.1 航司映射
AIRLINE_CODE_MAP = {
"TK": "TK", "MU": "MU", "VJ-SGN": "VJ", "BR-TPE": "BR",
"ZH": "ZH", "CZ 美线": "CZ", "CZ 欧线": "CZ", "CZ 客机美线": "CZ",
"CZ 客机欧线 ": "CZ", "CZ腹仓": "CZ", "CA欧线": "CA",
"CA美线": "CA", "QR货机": "QR", "QR联运": "QR", "RA-KTM": "RA", "KE": "KE",
"DT": "DT",
}
3.2 Sheet 规则表
| Sheet名 | 航司 | 散托增量 | w45_fallback | ratio_to_cargo | transit_strict | transit_merged | 特殊 |
|---------|------|----------|-------------|----------------|----------------|--------------|------|
| TK | TK | 1 | - | False | False | True | 无比重列;默认货型 1:1、比重 0-9999;中转地合并单元格 |
| MU | MU | 2 | True | True | False | 只提普货 |
| VJ-SGN | VJ | 0 | True | False | False | 只提B舱 |
| BR-TPE | BR | 0 | True | True | False | 跳转点模式、托盘按行提取 |
| CZ 美线 | CZ | 2 | False | True | False | 45KG为空不fallback |
| CZ 欧线 | CZ | 2 | True | False | True | 中转地仅三字码 |
| CZ 客机美线 | CZ | 2 | True | False | True | 中转地仅三字码 |
| CZ 客机欧线 | CZ | 2 | True | False | True | 中转地仅三字码 |
| CZ腹仓 | CZ | 2 | True | True | False | 目的/→,不拆分;priority 普货>a3>a2 |
| CA欧线 | CA | 2 | False | False | True | 45KG列为空不fallback |
| CA美线 | CA | 2 | True | True | True | 中转地仅三字码 |
| QR货机 | QR | 2 | - | False | False | default_cargo_type=1:1、只提普货+散箱 |
| QR联运 | QR | 2 | - | False | False | default_cargo_type=1:1、只提普货 |
| KE | KE | 0 | True | False | False | |
| ZH | ZH | 0 | True | False | False | |
| RA-KTM | RA | 0 | True | False | False | | |
| DT | DT | 0 | - | False | False | default_cargo_type=1:1 | 比重列和货型列均为空,默认全段 1:1(0-9999);散托增量为空 |
3.3 四重 boolean 详解(易错)
| 参数 | True 时做什么 | False 时做什么 |
|------|-------------|---------------|
| ratio_to_cargo | 比重推导 + block级45KG追踪 | 跳过比重推导 |
| w45_fallback | 45KG为空时用100KG填充 | 保持空(如CZ美线后续档) |
| transit_strict | 中转地必须纯三字码(CZ/CA欧线) | 原样保留 |
| transit_merged | 中转地是合并单元格,不清空继承值 | 目的港变化时清空中转地(防继承泄漏) |
四、深圳 Sheet 配置
| Sheet名 | 航司 | 散托增量 | 备注 | |---------|------|----------|------| | TK | TK | 2 | 无>=基准日数据 | | CA 直航 | CA | 2 | | | CA 欧洲中转 | CA | 2 | 中转数据 | | CZ 直航 | CZ | 2 | | | CZ 中转 | CZ | 2 | 中转数据 | | CZ ORD | CZ | 2 | >=基准日+3 | | HU | HU | 2 | | | JG BKK SGN | JG | 0 | | | O3 LAX | O3 | 0 | | | CI | CI | 0 | |
五、核心提取逻辑
5.1 表头查找(find_header_row)
- 搜索含「目的地」+「起运地」的行
- 排除含「转运」开头的转运表标题行
- 识别列:目的地/起运地/中转地/MIN/N/+45KG/+100KG/+300KG/+500KG/+1000KG/比重/货型/频率/备注
5.2 价格行判断(is_price_row)
跳过条件:
- 前 2 列含「航班时刻表」「始发站」「目的站」「参考二程」「FlightType」「AC Type」
- 前 2 列是 D1-D7(航班时刻表头)
- 所有重量段(+45/100/300/500/1000)全无值或 ≤1
- N列(单价)≤10 且 MIN列 ≤100
5.3 转运数据过滤
- 行中前几列含「转运」→ 标记进入转运区
- 转运区中遇到「目的地」或价格>100 → 退出
- 转运区内数据全部跳过
5.4 非数据行跳过(is_note_row)
前几列含:收运说明/仓储/备注/费用/更新/报价已含/报关/加班/叉车/仓租/截单
六、生效日期处理
6.1 提取方式
- 扫描表头区域(前20行)正则匹配
YYYY-MM-DD→default_eff_date - 每行数据前扫描
extract_effective_date_from_row动态更新 →cur_eff_date - 若都无 → 默认
"2026-05-18"(文件日期)
6.2 过滤
BASE_DATE = "2026-05-18" # ← 每批次修改
df2 = df2[df2["开始生效日期"] >= BASE_DATE]
6.3 格式
输出:"YYYY-MM-DD HH:MM:SS" 格式
七、比重引擎(ratio_engine.apply_ratio_engine)
提取完成后调用,参数:
df2 = apply_ratio_engine(df, src_col='起始港', dst_col='目的港', airline_col='航司', cargo_col='货型')
关键:
- 链式比重:gt档按阈值升序,end=下档start,末档=9999
- lt档:独立区间 [0, lt值]
- 1:1档:start=0,end=首gt档阈值或9999
- 货型清理:保留
1:\d+>\d+<\d+三种格式
八、散托类型与增量(优先级)
- 行级备注含
托盘+X→ 散货,增量=X(正则r'托盘[//\s]*\+(\d+)') - 表头标题行含
托盘+X→ block 初始值 - Sheet 规则默认值(如 MU=2, CZ=2, CA=2)
- 值为 0 → 增量空字符串
''
散托类型判定
- 有托盘增量(行级/block级) → 「散货」
- 货型列明确写「散货」/「托盘」 → 按描述
- 以上都无 → 「散货/托盘」
BR-TPE 特殊规则
tray_from_remark=True:只有备注含「托盘+X」才填增量- 无备注 → 增量为空(不继承 Sheet 默认值)
- 中转地 → 跳转点(
jump_point=True) - 目的地含
/→ 拆分多行
九、CZ 腹仓特殊规则
- 目的地含
/不拆分,只替换为,(如KTI/PNH→KTI,PNH) cargo_filter_priority: ["普货", "a3", "a2"]- 同一 block 中优先取高级别货型,低级别跳过
十、QR 货机/联运特殊规则
default_cargo_type: "1:1"(比重列为空时默认货型)- QR货机只提「普货」+「散箱」
- QR联运只提「普货」
- 去重时包含转运点(区分 DOH 和 KUL)
十一、常见坑和修复记录
坑1:CZ 美线 w45_fallback=False
Block 首行有 45KG,后续档为空。不应 fallback。
坑2:CA 欧线 ratio_to_cargo=False
45KG 列全为空,不应 fallback 到 100KG。
坑3:QR 货型为 1:1
比重列为空,需 default_cargo_type="1:1"。
坑4:多行备注含换行符
remark_full = str(remark).replace('\n', ' ').replace('\r', ' ')
坑5:散托类型覆盖问题
st_type='散货' 优先级最高,不被后续空备注覆盖。只有 st_type=='散货/托盘' 才允许更新。
坑6:int() 转换价格丢失小数
禁止 int(),价格列保留 float。
坑7:TK 中转地合并单元格丢失
TK Sheet 中转地列是合并单元格(Rows 9-149 全为 IST),xlrd 读取 .xls 时只在首行返回值,其余行为空。
修复:添加 transit_merged=True 标记,目的港变化时不清空中转地继承值。
elif not transit_val and dest_val and dest_val != cur_dest:
if not rules.get("transit_merged"): # TK 等合并单元格不清空
cur_transit = ""
坑8:停飞/停航/暂停行必须整行跳过(0615新增)
频次列含 停飞、停航、暂停 时,不属于有效运价,必须整行跳过;不要只做频次清洗。注意脚本判断要用 sname 或 freq_raw,不要写成 if sh == "CZ腹仓"(sh 是 sheet 对象,会导致判断永远不命中)。
坑9:无比重列 Sheet 不得输出空比重(0615新增)
TK、QR货机、QR联运等无比重列/比重为空的有效价格行,必须设置默认货型 1:1,并输出 开始比重=0、结束比重=9999。禁止让开始比重、结束比重、货型为空。
坑10:新增航司必须配置 default_cargo_type(0622新增)
症状:DT 航司输出时 开始比重=None、结束比重=None、货型=None。
原因:DT 比重列和货型列在源数据中全为空,但 get_sheet_rules() 未配置 default_cargo_type: "1:1",导致 ratio_lo/ratio_hi 均为 None,output 行没有默认值。
修复:在 DT 的 rules dict 中添加 "default_cargo_type": "1:1"。凡是比重列为空的 Sheet,必须检查是否缺少此配置。
十二、频率归一化
- "二程 D13467" → "D13467"(去掉前缀"二程 ")
- "CZ daily窄体" → "Daily"(匹配 Daily 关键词)
- "1357.0" → "D1357"(float→int→加D前缀)
- D号码规范化:收集所有 D+数字,取最长、去重、排序拼接
十三、脚本模板
广州脚本模板:/Users/hantao/WorkBuddy/oone/run_cimc_can.py
深圳脚本模板:/Users/hantao/WorkBuddy/oone/run_cimc_szx.py
新批次时:
- 复制最新版本脚本
- 更新
DEFAULT_SOURCE_FILE指向新文件 - 更新
BASE_DATE为文件日期 - 对照源文件确认 Sheet 规则是否需要调整
- 运行 → 验证 → 上传 WPS
十四、输出验证
from columns_24 import COL_24, validate_columns
# CIMC 脚本内联 24 列定义(不使用 COL_24 常量)
# 确保列名完全一致:
COLS = ["起始港", "目的港", "航司", "开始比重", "结束比重", "货型",
"45KG", "100KG", "300KG", "500KG", "1000KG",
"散托类型", "开始生效日期", "分泡", "频次", "Remark",
"跳转点", "转运点", "转运费增量值(RMB/KG)", "转运费最低收费(/票)",
"备注", "来源", "价格编号", "散托增量"]
Scan to join WeChat group