用 Python 给亚马逊批量上传表做必填字段与尺码格式自动校验
做亚马逊批量上传时,最怕的不是填表慢,而是填错了才发现:必填字段漏了、尺码写成了自由文本、价格带了货币符号,上传后整批报错,来回返工。本文用 Python + openpyxl 写一个上传前自动校验脚本,先把问题拦在本地,再生成一份错误行汇总,改完再上传。
一、先定规则,再写代码
校验之前,先把口径写死,否则每个人按自己的理解填,脚本也救不了。建议一张表只定一套规则:第一行是表头,从第二行开始是数据;必填字段包括 SKU、商品名称、品牌、价格、库存、尺码;尺码只允许枚举值,例如 XS、S、M、L、XL、XXL、均码;价格必须是大于 0 的数字,不能带货币符号或逗号;库存必须是大于等于 0 的整数。规则写进代码里,换品类时只改枚举和必填列表,不改主逻辑。
二、用 openpyxl 读表,保留行号
读表时不要只读值,要保留原始行号,因为报错一定要能定位到 Excel 的第几行。可以用 load_workbook 打开文件,取活动工作表,首行做表头映射:把表头文字去掉空格后映射到列号,后面按列号取值。这样即使列顺序调整,脚本也不用重写。读到空行要跳过,但要区分整行空白和部分字段空白,前者跳过,后者是必填缺失。
三、必填字段空值检查
对每一行,遍历必填字段列表,取值后做 strip 处理:空字符串、只有空格、None 都算空值。只要有一个必填为空,就记一条错误,写明行号、字段名和问题类型,例如第 12 行尺码为空。不要在第一条错误处就停下来,要把整行的问题一次报完,否则用户改一轮、跑一轮,效率很低。
四、尺码枚举校验与格式归一
尺码是最容易写花的字段:有人写小写 m,有人写 M 码,有人写均码带空格。处理办法是先归一化:去空格、转大写,再和枚举集合比对。归一化后仍不在枚举里的,记为尺码非法,并把原始值也写进错误汇总,方便核对。如果是服装以外的品类,把枚举换成该品类的规格集合即可,逻辑不变。
五、价格与库存的数值校验
价格字段先去掉首尾空格,如果是字符串形式的数字,先尝试转成 float;转失败或小于等于 0 的,记为价格非法。库存字段要求是整数:先看它是不是整数类型或整数形式的字符串,再检查是否小于 0。数值校验要和必填校验分开记,因为空和格式错是两种不同的改法,汇总里分开写,运营改起来更清楚。
六、错误行汇总输出
校验结束,生成两份结果:一份是控制台简报,打印总行数、通过行数、错误行数;另一份是 errors 表,每行包含原始行号、SKU、字段、原始值、错误原因。只输出错误行,不要把整表再复制一遍,这样改完后可以直接按行号回到原表修改。错误数为 0 时,打印校验通过可以上传,再去后台上传。
七、落地建议
这个脚本适合放在上传流程的第一步:下载模板、填表、跑校验、改错误行、再上传。模板更新时同步更新必填列表和尺码枚举;多人协作时把规则文件单独放一份,避免各人手里的版本不一致。先校验再上传,看起来多了一步,实际上省掉了后台报错、定位、返工的时间,批量越大,收益越明显。
核心代码思路如下:用 openpyxl 读表并建立表头映射,逐行做必填、尺码枚举、价格库存校验,把错误收集到列表,最后输出汇总。把规则抽成常量,脚本就能在不同品类间复用,这才是批量上传真正省力的地方。
import openpyxl
REQUIRED = ["SKU", "商品名称", "品牌", "价格", "库存", "尺码"]
SIZES = {"XS", "S", "M", "L", "XL", "XXL", "均码"}
wb = openpyxl.load_workbook("upload.xlsx")
ws = wb.active
headers = [str(c.value).strip() if c.value else "" for c in next(ws.iter_rows(min_row=1, max_row=1))]
col = {name: i for i, name in enumerate(headers)}
errors = []
for row in ws.iter_rows(min_row=2, values_only=False):
r = row[0].row
vals = {name: row[col[name]].value for name in REQUIRED if name in col}
if all(v is None or str(v).strip() == "" for v in vals.values()):
continue
for name in REQUIRED:
v = vals.get(name)
if v is None or str(v).strip() == "":
errors.append((r, vals.get("SKU"), name, v, "必填字段为空"))
size = vals.get("尺码")
if size is not None and str(size).strip() != "" and str(size).strip().upper() not in SIZES:
errors.append((r, vals.get("SKU"), "尺码", size, "尺码不在枚举内"))
print(f"错误行数:{len(errors)}")
for e in errors:
print(e)
- 点赞
- 收藏
- 关注作者
评论(0)