批量导入的老 CSV 是 GBK,chardet.detect 返回 latin1 置信度 0.73。按它解码再存 UTF-8,中文全变成 øà这样的串,原始字节已经找不回来。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
raw = open('old.csv', 'rb').read()
for enc in ('utf-8-sig', 'gb18030', 'big5'):
try:
text = raw.decode(enc); break
except UnicodeDecodeError:
continue
latin1 能解码任意字节序列,短文本和字节分布均匀的内容很容易被它拿到高分。探测器只看统计特征,不校验解码后的字符是否合理,GBK 的双字节就被拆成两个拉丁字符。这一点先确认清楚,后面就不用反复试。
「编码探测误判」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
改完隔一天再看一次,当场正常不代表能稳住。
具体做法是,候选编码按业务白名单排 先试 gb18030 再试 utf-8;解码后统计不可打印字符比例 超过阈值就换编码;转换前备份原文件 转坏还能重来;文件多的时候先抽样人工确认再批量跑。
改完照着核一遍,转出的 CSV 里中文正常显示 iconv 回转之后和原字节逐字节一致。
