NANMEI_002 价格提取 Skill
提取 NANMEI 中美航线(usdc.xlsx)运价表 → 24列标准输出 → 上传 WPS。
⚠️ 铁律:仅提取用户最新提交文件,禁止复制历史数据
- 禁止查看/引用/复制任何历史脚本中的 price/data 数组
- 禁止从历史输出文件直接读取数据
- 禁止硬编码历史文件路径作为源文件
- 每次提取必须从用户当前提交文件全新读取
- 有就是有,没有就是没有:不得用历史数据填补缺失值
一、核心参数
| 参数 | 值 |
|------|-----|
| 源文件 | 用户提交(通常为 usdc.xlsx) |
| Sheet | Central America |
| 起始港 | PVG(默认) |
| 价格编号 | nanmei_002 |
| 来源 | nanmei |
| 生效日期 | 动态(datetime.now()) |
| 45KG | 始终为空 |
| 引擎 | openpyxl(.xlsx) |
二、与 nanmei_001 的关键差异
| 差异点 | nanmei_001 | nanmei_002 |
|--------|-----------|-----------|
| 源文件 | usd.xlsx | usdc.xlsx |
| Sheet | Hoja1 | Central America |
| 生效日期 | 硬编码 2026-04-20 | 动态 datetime.now() |
| 数据块键 | (dest, carrier, routing) | (dest, carrier)(不含 routing) |
| 航司识别 | 排除 KGS/CBM/LOOSE/PALLET | 排除 KGS/CBM/KG |
| 散托解析函数 | parse_remark_for_san | parse_remark_for_san_and_usd |
| USD增量存在时 | 按 remark 判断 | 强制散货 |
| 无备注默认 | 散货/托盘 | 散货/托盘(⚠️ 禁止用列名缩写"散托") |
| 路由解析 | 标准三段 | dest段 strip / 后缀 |
三、强制流程
1. 确认源文件路径
2. openpyxl 加载 Central America
3. 第一遍扫描:行级状态采集(两遍架构同 001)
4. 第二遍处理:按 (dest, carrier) 分组 → 链式推导
5. 生成 24 列 DataFrame
6. 保存 → 自动上传 WPS → 删除临时文件
四、Excel 列映射
| col | 字段 | 作用 | |-----|------|------| | 1 | AOD | 目的地三字码 | | 2 | CARRIER | 航司代码 OR 比重(KGS/CBM>XXX) | | 3 | 100KG | 价格 | | 4 | 300KG | 价格 | | 5 | 500KG | 价格 | | 6 | 1000KG | 价格 | | 7 | Frequency | 频次 | | 8 | Routing | 路由(PVG-XXX-YYY-ZZZ) | | 10 | Remark | 备注 |
五、两遍处理架构
5.1 第一遍:行级状态追踪
# 状态变量
current_dest = None # col1 有值更新
current_carrier = None # col2 识别为航司更新
current_routing = None # col8 有值更新
current_origin = None # 从路由提取
current_transfer = [] # 从路由中段提取
current_freq = None # col7 有值更新
current_remark = None # col10 有值更新
5.2 目的港特殊处理
# 与 001 不同:col1 含 / 时用路由目的地
if '/' in str(col1 or ''):
current_dest = routing_dest # 从 col8 路由提取
5.3 第二遍:链式推导
# 数据块 = (dest, carrier) — 不含 routing
key = (row['dest'], row['carrier'])
blocks[key].append(row)
GT/LT/1:1 推导逻辑与 001 完全相同。
六、航司识别(is_carrier_code)
与 001 基本相同,额外排除条件:
| 条件 | 说明 |
|------|------|
| 含 KGS / CBM | 货型格式 |
| 含 KG | 新增排除(如 KG>500) |
| 多航司 / 分隔 | 每个段 2-4 位字母数字 |
七、散托类型判断(parse_remark_for_san_and_usd)
与 001 的关键差异:有 USD 增量 → 强制散货。
| 条件 | 散托类型 | 说明 |
|------|---------|------|
| 备注有 USD X.XX/KG | 散货 | 有增量 → 强制散货 |
| LOOSE CARTON ONLY / ONLY LOOSE | 散货 | 明确散货 |
| LOOSE + PALLET/CASE | 散货/托盘 | 混合 |
| PALLET / CASE / SKID | 托盘 | 纯托盘 |
| LOOSE | 散货 | 纯散货 |
| 无以上 | 散货/托盘 | 默认(⚠️ 禁止使用 "散托",那是列名缩写不是数据值) |
八、路由提取(extract_routing_info)
与 001 基本相同,差异:dest 和 transfers 会 strip / 后缀。
输入: "PVG-LHR-DFW/IAH-GRU"
→ origin="PVG", transfers=["LHR","DFW"], dest="GRU"
→ dest = re.sub(r'/.*$', '', dest) # 去掉 / 后部分
九、常见坑
坑1:散托默认值 = "散货/托盘"
002 无备注时默认值 = "散货/托盘",⚠️ 严禁使用列名缩写 "散托" 作为数据值。合法值只有:散货、托盘、散货/托盘。
坑2:USD 增量强制散货
有 USD 增量时,散托类型必须是 "散货",不看其他关键词。
坑3:col1 含 / 时目的地错误
如果 col1 = PTY/MGA,不能用 col1 作为目的地,必须从路由提取。
坑4:block_key 不含 routing
两个不同路由但同一 (dest, carrier) 会被合并推导。如果路由差异影响价格,需要注意。
坑5:is_carrier_code 排除 KG
KG>500 这类内容会被误识别为航司,必须排除。
坑6:合并单元格增量传播(⚠️ 高频 2026-05-25)
货型行的 col9 备注列在 Excel 中常是合并单元格,只有首行有 "usd X.XX/kg" 文本,后续行 col9 为空。
- 当前航司的 carrier remark 无增量时(如仅"中转费+18"),
inc='' - 第一个货型行(如 <140)从合并单元格备注中提取到
0.28 - 后续货型行(<120/<100/<80/>300/>500/>800)col9 为空 → 增量丢失
修复:货型行循环内维护 block_inc,遇到新增量即更新,后续行自动继承。
block_inc = inc # carrier 增量(可能为空)
for cargo_row in cargo_rows:
row_st, row_inc = parse_st_type_and_increment(mr9, mr11)
if row_inc:
block_inc = row_inc # 合并单元格首行 → 更新 block
final_inc = block_inc if block_inc else inc
十、脚本模板
当前脚本:/Users/hantao/WorkBuddy/oone/extract_nanmei_002_0525.py
源文件:用户提交
输出:nanmei_002_0525_output.xlsx(临时,上传后删除)
新批次时需更新 file_path 和生效日期即可。
微信扫一扫