Python 和 pandas 中文乱码的解决方法

pd.read_csv 报 UnicodeDecodeError,读出的中文变成 浣犲ソ,或者 to_csv 导出的文件用 Excel 打开是乱码?在 Python 中,关键就在 encoding 参数。下面是最常见的几种情况,已经出错的文件可以在上面直接修复。

支持文本和以下文件:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

例如 Excel 导出、数据库备份、字幕或网站代码。

修复

  1. 拖入文件或粘贴文本
  2. 自动修复
  3. 复制或下载
或把文件拖到这里
  • 无需上传。 文件直接在浏览器中修复,不会离开你的设备。

  • 服务器位于欧盟。 Mojibuster 运行在 芬兰(欧盟)的服务器上,受《通用数据保护条例》(GDPR)约束。 GDPR 全文(EUR-Lex,英文)

读取时报 UnicodeDecodeError

pd.read_csv 默认按 UTF-8 读取。如果文件是用 GBK 保存的(例如 Excel 另存的“CSV(逗号分隔)”、银行流水或旧系统的导出文件),就会报 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6,而 D6 D0 正是 GBK 中的“中”。这时指定编码即可:

  • pd.read_csv('data.csv', encoding='gb18030'):GB18030 包含 GBK 和 GB2312 的全部字符,生僻字也不会出错,最稳妥。
  • encoding='gbk' 大多数情况下也可以,但遇到少数 GBK 没有收录的字时会报错。
  • 文件开头有 BOM 时用 encoding='utf-8-sig',否则第一个列名前会多出一个看不见的 \ufeff,按列名取值时报 KeyError。
  • 不知道是什么编码?把文件拖进 Mojibuster,它会自动识别编码,并保存为 UTF-8。

'gbk' codec can't decode:open() 的默认编码

反过来的错误同样常见:open('data.txt') 不写 encoding 时,Python 在 Windows 上使用系统编码,简体中文 Windows 上就是 GBK(cp936)。读取 UTF-8 文件时会报 UnicodeDecodeError: 'gbk' codec can't decode byte …,或者不报错,却读出 浣犲ソ。所以请始终写上 encoding='utf-8',或者设置环境变量 PYTHONUTF8=1。根据 PEP 686,今后的 Python 版本会默认使用 UTF-8。

to_csv:用 Excel 打开是乱码

df.to_csv('export.csv') 写出的是不带 BOM 的 UTF-8。中文版 Excel 双击打开时会按 GBK 读取,中文就成了乱码。改用 encoding='utf-8-sig' 写出带 BOM 的文件,Excel 就能识别 UTF-8。详见 Excel 打开 CSV 乱码。

pandas 导出的 CSV 用 Excel 双击打开时

乱码

濮撳悕,鍩庡競,閲戦
寮犱紵,涓婃捣,1250
鏉庡,娣卞湷,980

修复后

姓名,城市,金额
张伟,上海,1250
李娜,深圳,980

如果乱码已经被保存进文件,单个值可以用 s.encode('gbk').decode('utf-8') 还原,但只要有一个单元格本来就是正确的,这个方法就会出错。更简单的办法是先用 Mojibuster 修复文件,再用 pandas 读取。

requests 爬虫中文乱码

requests 根据响应头 Content-Type 决定 response.text 的编码。如果文本响应的头部没有写字符集,它会按 ISO-8859-1 解码:UTF-8 网页变成 ä½ å¥½,GBK 网页变成 ÄãºÃ。先设置 response.encoding = response.apparent_encoding(或直接写 'utf-8'、'gbk'),再读取 response.text。

如果读写时用过 errors='replace' 或 encoding_errors='replace',无法转换的字已经变成 ? 或 �,原来的信息丢失了,无法恢复。更多乱码类型见 乱码是什么。

常见问题

gbk、gb2312、gb18030 该用哪个?

读取时用 gb18030。它包含 GBK 和 GB2312 的全部字符,能读的文件最多。给旧系统写文件时,按对方的要求选择。

有修复乱码的 Python 库吗?

有,例如 ftfy,不过它主要针对西文乱码。处理单个文件又不想写代码时,用 Mojibuster 更快,保存前还能看到每一处改动。

分隔符和数字会被改动吗?

不会。Mojibuster 只修改乱码的字符,逗号、引号和换行都保持原样。

更多指南