首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >用 Python 清洗多平台电商商品数据:SKU 标准化、去重与映射校验

用 Python 清洗多平台电商商品数据:SKU 标准化、去重与映射校验

原创
作者头像
用户12879075
发布于 2026-11-06 15:23:37
发布于 2026-11-06 15:23:37
940
举报

多平台开店的商家准备上线进销存或网店ERP时,第一步往往不是装软件,而是整理商品数据。淘宝、拼多多、抖店各导出一份商品表,同一件商品在三个平台上的标题、规格写法、商家编码各不相同,有的甚至没填编码。这些数据不清洗就导入系统,结果就是同一商品被拆成好几个,库存永远对不上。

本文用 Python + pandas 实现一个可直接运行的清洗流程(Python 3.8+,需安装 pandas):文本标准化、规格解析、编码规范化、缺失编码推断和映射校验,最后输出一张可以导入ERP的 SKU 映射表。

一、多平台商品数据有哪些“脏”?

先看一个典型的例子,同一款白色 M 码 T 恤,在三个平台上是这样的:

平台

商品标题

规格

商家编码

淘宝

纯棉短袖T恤 男女同款

白色/M

FZ-001-WH-M

拼多多

纯棉短袖T恤(男女同款)

白色 M码

(空)

抖店

纯棉 短袖T恤

白-M

FZ001WHM

归纳起来,常见问题有五类:

  1. 全角半角混用:“T恤”和“T恤”、“(”和“(”;
  2. 空格和大小写不一致:“ FZ-001-WH-XL ”带首尾空格,“bw500bk”是小写;
  3. 规格写法各异:“白色/M”“白色 M码”“白-M”说的是同一个规格;
  4. 编码格式不统一:有的带分隔符,有的不带;
  5. 编码缺失:平台上没填商家编码。

人工处理几十个商品还行,几百上千个 SKU 就必须用程序批量处理。

二、整体思路

代码语言:javascript
复制
各平台导出表 ──> 合并
              ──> 文本标准化(全角转半角、大写、去空格)
              ──> 规格解析(颜色、尺码)
              ──> 编码规范化(统一成 品类-款号-颜色-尺码)
              ──> 缺失编码推断(按同款已知编码 + 规格补全)
              ──> 映射校验(未映射 / 推断待确认 / 规格冲突)
              ──> 输出 SKU 映射表

编码规则采用“品类(2位字母)-款号(3位数字)-颜色(2位字母)-尺码”,例如 FZ-001-WH-M 表示服装、001 款、白色、M 码。规则本身可以按企业实际调整,关键是全公司只用一套。

三、完整代码

代码使用内置的示例数据,复制即可运行;实际使用时,把第 1 步换成 pd.read_excel() 读取各平台导出的文件。

代码语言:javascript
复制
import re
import unicodedata
import pandas as pd

# 1. 模拟三个平台导出的商品数据(实际使用时换成 pd.read_excel 读取各平台导出文件)
taobao = pd.DataFrame({
    "平台": "淘宝",
    "商品标题": ["纯棉短袖T恤 男女同款", "纯棉短袖T恤 男女同款", "保温杯500ml"],
    "规格": ["白色/M", "白色/L", "黑色"],
    "商家编码": ["FZ-001-WH-M", "FZ-001-WH-L", "BW-500-BK"],
})
pdd = pd.DataFrame({
    "平台": "拼多多",
    "商品标题": ["纯棉短袖T恤(男女同款)", "保温杯 500ML"],
    "规格": ["白色 M码", "黑色"],
    "商家编码": ["", "bw500bk"],
})
douyin = pd.DataFrame({
    "平台": "抖店",
    "商品标题": ["纯棉 短袖T恤", "纯棉 短袖T恤"],
    "规格": ["白-M", "白-XL"],
    "商家编码": ["FZ001WHM", " FZ-001-WH-XL "],
})
raw = pd.concat([taobao, pdd, douyin], ignore_index=True)

# 2. 文本标准化:全角转半角、统一大小写、去多余空格
def norm_text(s):
    if pd.isna(s):                     # 读 Excel 时空单元格是 NaN,要先处理
        return ""
    s = unicodedata.normalize("NFKC", str(s))
    return re.sub(r"\s+", " ", s).strip().upper()

# 3. 规格解析:把各平台五花八门的写法统一成 颜色 + 尺码
COLOR_MAP = {"白色": "WH", "白": "WH", "黑色": "BK", "黑": "BK"}
SIZES = ["XXL", "XL", "L", "M", "S"]

def parse_spec(spec):
    spec = norm_text(spec)
    color = next((code for word, code in COLOR_MAP.items() if word in spec), "")
    size = next((sz for sz in SIZES if re.search(rf"(?<![A-Z]){sz}(?![A-Z])", spec)), "")
    return color, size

# 4. 商家编码标准化:去空格、去分隔符后重新按段拼接
def norm_code(code):
    c = re.sub(r"[^A-Z0-9]", "", norm_text(code))
    # 正则对应本文的编码规则,换成自己的规则时同步修改
    m = re.fullmatch(r"([A-Z]{2})(\d{3})([A-Z]{2})([A-Z]{0,3})", c)
    if not m:
        return ""
    return "-".join(p for p in m.groups() if p)

df = raw.copy()
df[["颜色", "尺码"]] = df["规格"].apply(lambda s: pd.Series(parse_spec(s)))
df["标准编码"] = df["商家编码"].apply(norm_code)

# 5. 编码缺失的行:按 款号 + 颜色 + 尺码 从同款已知编码中推断
known = df[df["标准编码"] != ""].copy()
known["款号"] = known["标准编码"].str.extract(r"^([A-Z]{2}-\d{3})")
style_by_title = {}
for _, r in known.iterrows():
    key = re.sub(r"[^一-龥A-Z0-9]", "", norm_text(r["商品标题"]))
    style_by_title.setdefault(key, r["款号"])

def infer_code(r):
    if r["标准编码"]:
        return r["标准编码"], "原编码"
    key = re.sub(r"[^一-龥A-Z0-9]", "", norm_text(r["商品标题"]))
    style = next((v for k, v in style_by_title.items() if k in key or key in k), None)
    if style and r["颜色"]:
        return "-".join(p for p in [style, r["颜色"], r["尺码"]] if p), "推断"
    return "", "无法推断"

df[["系统编码", "来源"]] = df.apply(lambda r: pd.Series(infer_code(r)), axis=1)

# 6. 映射校验
unmapped = df[df["系统编码"] == ""]
inferred = df[df["来源"] == "推断"]
sku_list = df[df["系统编码"] != ""]["系统编码"].drop_duplicates().sort_values()

# 冲突校验:同一个系统编码,解析出的颜色/尺码必须一致
spec_cnt = df[df["系统编码"] != ""].groupby("系统编码")[["颜色", "尺码"]].nunique()
conflict = spec_cnt[(spec_cnt["颜色"] > 1) | (spec_cnt["尺码"] > 1)]

print("清洗后的映射表:")
print(df[["平台", "规格", "商家编码", "系统编码", "来源"]].to_string(index=False))
print(f"\n去重后的系统SKU:{len(sku_list)} 个 -> {', '.join(sku_list)}")
print(f"需人工确认的推断编码:{len(inferred)} 条;无法映射:{len(unmapped)} 条;规格冲突:{len(conflict)} 个")

# 7. 导出结果,供导入ERP前人工复核(需安装 openpyxl)
# df.to_excel("SKU映射表.xlsx", index=False)

运行结果:

代码语言:javascript
复制
清洗后的映射表:
 平台    规格           商家编码         系统编码  来源
 淘宝  白色/M    FZ-001-WH-M  FZ-001-WH-M 原编码
 淘宝  白色/L    FZ-001-WH-L  FZ-001-WH-L 原编码
 淘宝    黑色      BW-500-BK    BW-500-BK 原编码
拼多多 白色 M码                 FZ-001-WH-M  推断
拼多多    黑色        bw500bk    BW-500-BK 原编码
 抖店   白-M       FZ001WHM  FZ-001-WH-M 原编码
 抖店  白-XL  FZ-001-WH-XL  FZ-001-WH-XL 原编码

去重后的系统SKU:4 个 -> BW-500-BK, FZ-001-WH-L, FZ-001-WH-M, FZ-001-WH-XL
需人工确认的推断编码:1 条;无法映射:0 条;规格冲突:0 个

7 行平台商品最终归并为 4 个系统 SKU:三个平台的白色 M 码 T 恤都对应到 FZ-001-WH-M,小写的 bw500bk 被规范成 BW-500-BK,带空格的编码也被正确识别。

四、关键步骤说明

1. 为什么先判断空值,再用 unicodedata.normalize("NFKC")? 用 read_excel 读取时,空单元格会变成 NaN,直接转字符串会得到 "nan",所以要先判断空值。 NFKC 规范化会把全角字母、数字、括号转换成半角,“T恤(男女同款)”会变成“T恤(男女同款)”。这一步放在最前面,后面的匹配规则才不用考虑全角半角两套写法。

2. 尺码匹配为什么要按 XXL、XL、L 的顺序? 如果先匹配 L,“XL”里的 L 也会被命中。按从长到短的顺序,并用前后不是字母的边界条件 (?<![A-Z]) 和 (?![A-Z]) 限定,可以避免误判。

3. 编码规范化的思路 先去掉所有非字母数字字符,再用正则按“2位字母 + 3位数字 + 2位字母 + 0到3位字母”切段,重新用短横线拼接。这样 FZ001WHM、fz-001-wh-m、FZ-001-WH-M 都会得到同一个结果。不符合规则的编码返回空值,留给后续推断或人工处理。

4. 缺失编码的推断 先从已有编码的商品里提取“款号”,以标准化后的标题为键建立对照;遇到编码缺失的行,用标题做包含匹配找到款号,再拼上解析出的颜色和尺码。推断出来的编码标记为“推断”,必须人工确认后再导入,不能直接当成准确结果。

5. 三项校验

  • 无法映射:既没有编码、也推断不出来的商品,需要人工补录;
  • 推断待确认:程序补全的编码,逐条核对;
  • 规格冲突:同一个系统编码解析出了不同的颜色或尺码,说明原始编码或规格填错了。

三项都清零后,映射表才可以导入。

五、实际使用时的注意事项

  1. 颜色字典要按自己的商品补全:示例只放了白、黑两个颜色,实际要把“米白”“象牙白”这类叫法都映射到统一代码。
  2. 组合装单独处理:“两件装”“套装”应在ERP里建组合商品,按组成扣减单品库存,不要强行映射成单个 SKU。
  3. 推断只是辅助:标题相似不代表是同一款,推断结果一定要人工复核。
  4. 从源头解决:清洗完成后,把各平台的“商家编码”统一改成系统编码,以后新上架商品先定编码再上架,就不用反复清洗了。

六、清洗好的数据怎么用?

清洗后的 SKU 映射表有两个用途:

  • 导入ERP建立商品档案:系统编码作为商品主数据,平台规格和商家编码作为对应关系;
  • 完成平台商品对应:店铺授权后,平台订单按商家编码自动匹配到系统商品,库存才能统一扣减和同步。

以网上管家婆网店ERP为例,它在进销存的基础上增加了多平台订单处理和库存同步,据其系统内对接平台页面显示已对接200多个平台。商品资料导入的具体格式和字段,以所用版本的导入模板为准。

七、小结

  • 多平台商品数据的问题主要是全角半角、空格大小写、规格写法、编码格式和编码缺失五类;
  • 处理顺序是先标准化文本,再解析规格、规范编码,最后推断和校验;
  • 程序推断的结果只能作为辅助,必须人工确认;
  • 清洗完成后,从源头统一各平台商家编码,才能一劳永逸。

作者:俊达软件(广州俊达软件技术有限公司),网上管家婆授权全国经销商,从事进销存与网店ERP的上线实施。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、多平台商品数据有哪些“脏”?
  • 二、整体思路
  • 三、完整代码
  • 四、关键步骤说明
  • 五、实际使用时的注意事项
  • 六、清洗好的数据怎么用?
  • 七、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档