现场是这样的。运营从 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 兜底读取,比反复试编码可靠。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189