Python读取CSV中文乱码怎么办?encoding编码设置指南

蓝鲸
蓝鲸
发布时间:2026-11-02| 7人浏览过
原创

针对Python读取CSV文件时常见的中文乱码问题与UnicodeDecodeError报错,详细梳理UTF-8、UTF-8-SIG、GBK及GB18030的编码机制,提供标准库csv与Pandas的encoding参数配置方案、排查四步法与选型速查。

核心解决结论:在 Python 中读取 CSV 文件发生中文乱码或触发 UnicodeDecodeError,本质上是“文件写入时使用的二进制编码格式”与“读取时指定的解码格式”不一致。只需在 open() 函数或 pandas.read_csv() 中显式传入匹配的 encoding 参数(最常见为 utf-8、utf-8-sig、gbk 或 gb18030),即可彻底解决乱码问题。

一、为什么会发生中文乱码?核心原理解析

CSV(Comma-Separated Values)本质上是一个纯文本文件。计算机在硬盘上存储任何文本时,都必须先将其转换为一系列 0 和 1 组成的二进制字节(Byte)。当我们读取文件时,程序又需要按照某种对照规则将字节还原成字符,这个过程叫做“解码”(Decoding)。

Python 3 默认在读取文本文件时采用系统的默认编码(在 Windows 下通常是系统的 ANSI 代码页,如 CP936;在 Linux 和 macOS 下通常是 UTF-8)。乱码或解码崩溃通常发生在以下几种典型情形:

  • 用 UTF-8 解码 GBK 编码的文件:GBK 编码采用双字节表示中文字符,若其字节组合不符合 UTF-8 的多字节前缀规则,Python 解码器会直接中断并抛出 UnicodeDecodeError: 'utf-8' codec can't decode byte ...。
  • 用 GBK 解码 UTF-8 编码的文件:UTF-8 的中文字节被强行拆解为 GBK 双字节,通常不会直接报错,但文字会显示为完全无法阅读的混乱字符(如“测试”或“锟斤拷”)。
  • 未处理 UTF-8 BOM 标记:Windows 平台下的 Excel 导出 CSV 时,常在文件开头加入 3 个不可见字节 \xef\xbb\xbf(称为 Byte Order Mark,BOM)。若用普通的 utf-8 读取,第一个字段的列名会被解析为 \ufeff姓名,导致通过列名索引字段时 KeyError。
Python读取CSV中文乱码怎么办?encoding编码设置指南
图 1:底层字节编码与 Python 读取解码匹配机制

二、Python 标准库读取 CSV 的 encoding 设置

使用 Python 原生内置的 csv 模块时,其本身并不直接负责打开物理文件,而是依赖内建的 open() 函数。因此,编码设置的关键在于 open() 中的 encoding 形参。

1. 标准规范写法

强烈建议始终在 open() 中显式指定 encoding,不要依赖系统默认值。例如读取标准的 UTF-8 文件:

import csv

# 显式指定 encoding='utf-8',避免不同操作系统默认编码差异
with open('data_utf8.csv', mode='r', encoding='utf-8', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

2. 处理中文 Windows 环境导出的 CSV(GBK 与 GB18030)

如果 CSV 文件由简体中文版 Microsoft Excel 直接点击“另存为 CSV”生成,其默认采用的编码通常为 ANSI(在简体中文 Windows 下为 GBK / CP936)。在读取此类文件时,应将 encoding 设为 gbk 或更推荐的 gb18030:

import csv

# 推荐使用 gb18030,它是 GBK 的超集,包含更多生僻汉字和少数民族字符
with open('excel_export.csv', mode='r', encoding='gb18030', newline='') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row)
避坑提醒:为什么优先选用 gb18030 而非 gbk?

GB18030 是中国国家强制标准,完全向后兼容 GBK 和 GB2312。部分人名、地名、特殊符号(如“镕”、“赟”、“䶮”等)在 GBK 中不存在,读取时会抛出异常;改用 gb18030 即可顺利解码并完全规避此类生僻字报错。

3. 消除首列 BOM 头:utf-8-sig

如果 Excel 在导出时选用了“CSV UTF-8 (逗号分隔) (*.csv)”,Excel 会在文件起始插入 3 个字节的 BOM 头。使用 encoding='utf-8' 读取时,虽然不会报错,但首个字段会被附加 \ufeff,例如字典键会变成 '\ufeff姓名' 而不是 '姓名'。此时必须使用专门的 utf-8-sig:

with open('excel_utf8_bom.csv', mode='r', encoding='utf-8-sig', newline='') as f:
    reader = csv.DictReader(f)
    # 输出表头列表,首列不再带有 \ufeff 前缀
    print(reader.fieldnames)

三、Pandas 库中的 encoding 参数设置与容错处理

在数据分析领域,Pandas 的 pd.read_csv() 是读取 CSV 的主力工具。它的底阶核心解析器默认使用 utf-8,如果遇到其他编码的文件,同样会直接抛出 UnicodeDecodeError。

1. Pandas 基础编码参数调用

import pandas as pd

# 场景 1:读取标准 UTF-8 文件
df_utf8 = pd.read_csv('data.csv', encoding='utf-8')

# 场景 2:读取带有 BOM 的 Excel UTF-8 文件
df_sig = pd.read_csv('data_excel_bom.csv', encoding='utf-8-sig')

# 场景 3:读取 Windows Excel 默认 ANSI/GBK 导出的 CSV
df_gbk = pd.read_csv('data_excel_ansi.csv', encoding='gb18030')

2. 紧急容错参数:encoding_errors(谨慎使用)

在 Pandas 1.3.0 及更高版本中,pd.read_csv() 新增了 encoding_errors 参数(对应底层 Python 解码错误处理机制)。当文件中混入了少量受损或无法识别的脏字节时,可以通过该参数防止程序直接崩溃:

# 遇到无法解码的损坏字节时,替换为官方占位符(通常是 ? 或 ),不中断程序
df_replace = pd.read_csv('dirty_data.csv', encoding='gb18030', encoding_errors='replace')

# 直接忽略并跳过无法解码的字节(存在字符丢失风险,不推荐用于正式数据核算)
df_ignore = pd.read_csv('dirty_data.csv', encoding='utf-8', encoding_errors='ignore')
Python读取CSV中文乱码怎么办?encoding编码设置指南
图 2:内置 csv 模块与 Pandas 在编码调用上的区别与配合建议

四、未知编码 CSV 文件的排查四步法

面对来源不明的 CSV 文件,切忌盲目猜测。建议按照以下顺序建立排查机制:

Python读取CSV中文乱码怎么办?encoding编码设置指南
图 3:针对未知来源 CSV 文件的规范排查步骤流程

采样自动检测编码的完整脚本

对于批量文件或体积过大的 CSV,推荐读取前 10KB 字节进行探测,既轻量又高效:

import charset_normalizer

def detect_encoding(file_path):
    # 以二进制模式读取前 10240 字节,避免读取整个大文件浪费内存
    with open(file_path, 'rb') as f:
        raw_bytes = f.read(10240)
    
    result = charset_normalizer.from_bytes(raw_bytes).best()
    if result:
        return result.encoding
    return 'utf-8'  # 默认兜底推荐

# 实际调用示例
detected = detect_encoding('unknown_data.csv')
print(f"检测到的文件编码为: {detected}")

# 接着用检测出的编码进行读取
with open('unknown_data.csv', 'r', encoding=detected) as f:
    # 执行常规处理...
    pass

五、编码选型速查与决策指南

为避免反复调试,可根据数据生成方与运行平台直接锁定 encoding 取值:

数据生成来源 文件特征 / 表现 推荐 encoding 参数 备选或注意事项
简体中文 Windows Excel 直接保存 默认 ANSI 编码,通常包含各类汉字 gb18030 gbk(若无生僻字时可用)
Excel 另存为“UTF-8 CSV” 文件头包含 3 字节 BOM(\xef\xbb\xbf) utf-8-sig 用 utf-8 会导致首字段多出 \ufeff
现代 Web API / MySQL / Linux 标准无 BOM 的 UTF-8 编码文本 utf-8 国际通用主流,推荐跨平台使用
中国台湾/中国香港地区老系统 传统繁体中文,含大五码体系字符 big5 / cp950 gb18030 也能解码大部分常用繁体
第三方抓取 / 数据源杂乱 多种编码混合,或包含部分乱码字节 gb18030 配合 encoding_errors='replace' 优先使用 charset_normalizer 自动探测
Python读取CSV中文乱码怎么办?encoding编码设置指南
图 4:CSV 中文编码场景决策树与最终配置指引

六、长效维护建议

为了在团队协作与自动化数据管道中彻底杜绝中文乱码问题,建议确立以下规范:

  1. 读写明确指定:在编写代码时,养成对每一个 open() 或 pd.read_csv() / to_csv() 显式指定 encoding 的习惯,禁止省略或依赖环境默认设置。
  2. 向 Excel 用户交付时使用 utf-8-sig:如果你使用 Python 生成 CSV 文件并需要分发给使用 Windows Excel 的业务人员,保存时请设置 encoding='utf-8-sig'。这样 Excel 打开时能直接识别出 UTF-8,既不会发生中文乱码,又能保证多语言兼容性。
  3. 代码仓库内部统一 UTF-8:项目内部流转的数据一律强制转换为无 BOM 的 utf-8,减少中间处理环节的转码损耗。
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。