现场是这样的。运营从 Excel 导出的订单 CSV,用 pandas 按 utf-8 打开报 UnicodeDecodeError,提示 invalid continuation byte at position 128;改成 gbk 能读一部分,读到客户姓名又乱码,字段里还有几个生僻字。
中间走过弯路,把「没有 BOM,编码探测按概率猜错」当成主因,改完现象没变。
这类报错背后常见的原因有几处,逐个排除就行。文件实际是 GB18030,gbk 覆盖不到生僻字和扩展区;文件里混了几行 utf-8 的追加数据;读取时用默认的严格模式,一个坏字节整行失败。
探一次文件编码
python -c "from charset_normalizer import from_path;print(from_path('orders.csv').best().encoding)"
接着按 GB18030 打开并读一行验证
python -c "print(open('orders.csv',encoding='gb18030').readline())"
然后逐行探测找出混进来的异常行
python -c "for i,l in enumerate(open('orders.csv','rb'),1):
try: l.decode('gb18030')
except UnicodeDecodeError: print(i,l[:40])"
等前面都确认过,再统一转成带 BOM 的 utf-8 再入库
python -c "s=open('orders.csv',encoding='gb18030').read();open('orders_utf8.csv','w',encoding='utf-8-sig').write(s)"
怎么算真的好了,看的是同一批现象。整份文件按 GB18030 读取零错误,生僻字姓名在库里显示正常,转成 utf-8 后 pandas 读到的列数与表头一致。
这里还有个坑。gbk 不等于 GB18030,后者覆盖更全,中文 CSV 一律按 GB18030 兜底读取,比反复试编码可靠。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
