CIMC 深圳价格提取 Skill
提取 CIMC 深圳运价表 → 24列标准输出 → 上传 WPS。
⚠️ 铁律:仅提取用户最新提交文件,禁止复制历史数据
- 禁止查看/引用/复制任何历史脚本中的 price/data 数组
- 禁止从历史输出文件直接读取数据
- 禁止硬编码历史文件路径作为源文件
- 每次提取必须从用户当前提交文件全新读取
- 有就是有,没有就是没有:不得用历史数据填补缺失值
一、核心参数
| 参数 | 值 | |------|-----| | 起始港 | SZX | | 价格编号 | cimc_szx_001 | | 来源 | CIMC | | 引擎 | xlrd(.xls) | | 基准日期 | 2026-05-18(>=此日期才提取) |
二、与广州版的关键差异
| 差异点 | 广州 | 深圳 | |--------|------|------| | 起始港 | CAN | SZX | | 比重推导 | ratio_engine.py | 内置 chain_ratio() | | 合并单元格 | openpyxl merge_map | get_merged_value() 函数 | | 转运过滤 | 按"转运"关键词 | 按行特征判别 | | Sheet 数 | 16 | 17 | | 散托增量默认 | 各Sheet不同 | 仅 TK/CA/D0 有默认值 |
三、强制流程
1. 确认源文件路径(用户提交的 .xls 文件)
2. xlrd 加载 → 逐个 Sheet 提取
3. 合并单元格处理 → 转运数据过滤
4. 按 (dest, transit, eff_date) 分组收集
5. 链式比重推导 → 生成24列
6. 去重 → 保存 → 上传 WPS
四、深圳 Sheet 配置(17 个)
sheets = [
('TK', 'TK'), ('CA 直航', 'CA'), ('CA 欧洲中转', 'CA'),
('CA 美线中转', 'CA'), ('CZ 直航', 'CZ'), ('CZ 中转', 'CZ'),
('CZ ORD', 'CZ'), ('HU', 'HU'), ('D0 欧洲', 'D0'),
('D0 美线', 'D0'), ('JG BKK SGN', 'JG'), ('O3 LAX', 'O3'),
('O3 深圳始发', 'O3'), ('CI', 'CI'), ('BR', 'BR'),
('K6', 'K6'), ('WW KUL', 'WW'),
]
Sheet 级散托增量 ⚠️ 已废弃
# ⚠️ 2026-06-01 起:不再使用 Sheet 级默认增量!
# 散托增量仅从备注显式 +N 提取,无 +N → 增量空
# SHEET_INCREMENT 仅用于标记特定 Sheet 的默认散托类型(无实际作用,保留兼容)
SHEET_INCREMENT = {} # 全部清空,不设默认值
五、合并单元格处理(get_merged_value)
深圳版 不用 openpyxl merge_map,直接用 xlrd 的 merged_cells 属性:
def get_merged_value(ws, row_idx, col_idx):
for (r_lo, r_hi, c_lo, c_hi) in ws.merged_cells:
if r_lo <= row_idx < r_hi and c_lo <= col_idx < c_hi:
return ws.cell_value(r_lo, col_idx) # 返回左上角值
return ws.cell_value(row_idx, col_idx)
每行读取时同时保留 row(合并后)和 row_raw(原始值),用于:备注继承判断、空值区分。
六、转运数据过滤 ⚠️ 关键规则
深圳文件中含有转运辐射点价格表,必须过滤:
情况1:row[0] 有值且非 SZX/PVG/CAN → 转运数据
情况2:row[0] 为空,row[1] 是三字码但非 SZX,且 row[2]+row[3] 是数字 → 转运数据
正常价格行特征:row[1] == 'SZX'(起运港)
if row0_str and row0_str not in ['SZX', 'PVG', 'CAN']:
if row0_str not in ['区域', '深圳始发', '美线'] and not startswith('生效'):
is_transit = True
七、数据分组与链式比重推导
7.1 分组键
key = (current_dest, current_transit, eff_date)
data_groups[key] = {'items': [], 'freq': '', 'st_type': '散货/托盘', ...}
7.2 链式推导(chain_ratio)— 不同于广州的 ratio_engine
# lt 档(<XXX): 泡货,按阈值升序
# 1:1 档: 接在 lt 链后,覆盖到第一个 gt 档
# gt 档(>XXX): 重货,按阈值升序,末档=9999
仅当存在 <XXX 或 >XXX 时才走链式推导,否则每行独立输出 (0, 9999, cargo, ...)。
八、散托类型与增量判断 ⚠️ 2026-06-01 修正
🚨 铁律:散托增量仅从备注显式 +N 提取,无 +N → 增量为空
- 优先卡板/托盘+N:
卡板+2/KG、托盘+1/KG→ 散货,增量=N - 兜底任意+N(N ≤ 20):
直达点+1/KG、快件+1/KG→ 散货,增量=N - 无 +N 或 N > 20(如
+100KG、+500KG权重阈值)→ 散货/托盘,增量=空
增量解析函数:
def parse_increment(remark, default=None):
remark_str = str(remark) if remark else ''
# 1️⃣ 优先卡板/托盘 +N
m = re.search(r'(?:卡板|托盘)\s*\+(\d+(?:\.\d+)?)', remark_str)
if m:
return float(m.group(1))
# 2️⃣ 兜底任意+N(≤20 排除权重阈值误匹配)
m = re.search(r'\+(\d+(?:\.\d+)?)', remark_str)
if m:
val = float(m.group(1))
if val <= 20:
return val
return default
### Sheet 级散托增量 ⚠️ 已废弃
# ⚠️ 2026-06-01 起:不再使用 Sheet 级默认增量!
# SHEET_INCREMENT = {} # 全部清空,不设默认值
- 无 +N 备注 → 散货/托盘,增量=空
⚠️ 禁止行为:
- ❌ 使用 Sheet 级默认值硬塞增量(如 CA=2)
- ❌ 无 +N 备注时赋值增量 > 0
st_type 更新优先级(关键)
if st_type == '散货':
group['st_type'] = st_type # 散货优先级最高,不被覆盖
elif st_type and group['st_type'] == '散货/托盘':
group['st_type'] = st_type # 仅在未确定时才更新
九、生效日期处理
if '生效时间' in row_str:
eff = parse_date(row_str) # 从"生效时间:YYYY-MM-DD"提取
current_eff_date = eff
# 过滤 < 基准日期的数据
if current_eff_date and current_eff_date < datetime(2026, 5, 18):
continue # 跳过旧价格
十、多目的地格式
if '/' in dest:
dest_parts = dest.split('/') # CMB/MLE → ['CMB','MLE']
elif ' ' in dest:
dest_parts = dest.split(' ') # DXB DWC → ['DXB','DWC']
else:
dest_parts = [dest]
# 统一用英文逗号拼接
dests = [','.join(dest_parts)] # CMB,MLE
十一、输出格式
24列标准输出(HEADERS 直接用内联列表):
HEADERS = [
'起始港', '目的港', '航司', '开始比重', '结束比重', '货型',
'45KG', '100KG', '300KG', '500KG', '1000KG',
'散托类型', '开始生效日期', '分泡', '频次', 'Remark',
'跳转点', '转运点', '转运费增量值(RMB/KG)', '转运费最低收费(/票)', '备注',
'来源', '价格编号', '散托增量'
]
⚠️ 列19-20必须使用标准名 '转运费增量值(RMB/KG)'、'转运费最低收费(/票)',禁止使用简写 '转运费1'、'转运费2'。
十二、常见坑
坑1:合并单元格备注归属
备注归最后一行(比重最低行),xlrd 的 merged_cells 只返回第一行值。
坑2:多行备注 \n 处理
remark_full = str(remark).replace('\n', ' ').replace('\r', ' ')
坑3:st_type 覆盖问题
st_type='散货' 优先级最高,不被后续空备注覆盖。
坑4:转运数据误提取
必须严格检查 row[1] == 'SZX' 判断是否为正常价格行。
坑5:列名不标准
脚本内联 HEADERS 必须使用标准 24 列:'转运费增量值(RMB/KG)' 和 '转运费最低收费(/票)',禁止再用 '转运费1' / '转运费2'。
坑6:Sheet 级默认增量错误赋值 🔴 0610修复
症状:无 +N 备注的行被赋值增量=2(如 CA 直航亚洲线、TK 全线)
原因:旧代码用 SHEET_INCREMENT 做默认值 fallback
修复:仅 parse_increment() 返回非 None 时才设增量,否则增量为空
坑7:多+N冲突 - 卡板优先 🔴 0601修复
症状:备注含「直达点+1/KG」+「卡板+2/KG」,结果取到+1而非+2
原因:re.search 匹配第一个 +N = 直达点+1
修复:parse_increment() 分两步:
- 优先
(?:卡板|托盘)\s*\+N - 兜底任意
+N(N ≤ 20 排除 +100KG/+500KG 权重阈值)
坑8:鄂州机场代码 EZH→EHU 🔴 0601修复
症状:O3 鄂州始发 Sheet 目的地列填的是 EZH,但实际鄂州花湖机场三字码是 EHU
修复:Sheet 配置中 ('O3 鄂州始发', 'O3', 'EZH') → ('O3 鄂州始发', 'O3', 'EHU')
十三、脚本模板
脚本模板:/Users/hantao/WorkBuddy/oone/extract_cimc_szx.py
源文件:用户每次提交时指定
新批次时需更新:
SRC路径指向新文件- 基准日期
datetime(2026, 5, 18)改为文件日期 - Sheet 配置确认是否有新增/删减
- 运行 → 验证 → 上传 WPS
微信扫一扫