应显式指定encoding='gbk'(或'cp936')并配合errors='replace'容错,因Python 3默认UTF-8解码,而旧系统导出的文件多为GBK编码且可能含BOM,不指定编码或忽略BOM即触发UnicodeDecodeError。

直接用 open() 指定 encoding='gbk' 即可,但必须处理编码错误和 BOM 头——否则大概率报 UnicodeDecodeError 或开头多出乱码。
为什么默认读取会失败?
Python 3 默认用 UTF-8 解码文件,而旧系统(如 Windows 简体中文版下的 Excel、SQL Server 导出工具、某些 ERP)导出的 CSV/TXT 文件通常用 GBK 编码,且可能带 BOM(\ufeff)。不指定编码或忽略 BOM 就会触发 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 0 这类错误。
正确打开并读取 GBK 文件的写法
用 open() 显式声明编码,并根据需要处理 BOM:
with open('data.csv', encoding='gbk') as f:
content = f.read() # 自动跳过 BOM(CP936/GBK 实现已兼容)如果遇到个别文件开头有 BOM 且内容异常,可手动剥离:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
立即学习“Python免费学习笔记(深入)”;
- 先用
encoding='utf-8-sig'试读——仅适用于误标为 UTF-8 但实际是 GBK 带 BOM 的极少数情况(不推荐) - 更稳妥:用
encoding='gbk'+errors='replace'容错,再用.lstrip('\ufeff')清理 - 对逐行处理场景,建议用
for line in f:而非f.readlines(),避免一次性解码整文件引发内存或错误扩散
读取 CSV 文件时的特殊注意点
csv.reader 和 pandas.read_csv() 不接受 encoding 参数(pandas 0.25+ 支持,但底层仍调用 open()),所以关键仍在文件打开环节:
- 用
pandas.read_csv('file.csv', encoding='gbk')是最简方案(pandas 内部会传给open()) - 若用原生
csv模块,必须先用open(..., encoding='gbk')得到文本流,再传给csv.reader() - 避免用
encoding='gb2312'——它只是 GBK 的子集,遇到扩展汉字(如「镕」「瞭」)会报错;旧系统几乎都用完整 GBK(即 CP936)
跨平台和自动化脚本里的坑
Windows 上 gbk 通常能 fallback 成 cp936,但 Linux/macOS 默认不带 GBK locale,open(..., encoding='gbk') 可能抛 LookupError: unknown encoding: gbk:
- 解决方案:改用
encoding='cp936'(等价于 GBK,兼容性更好) - 或安装
chardet+charset-normalizer动态检测:chardet.detect(b'\xc4\xe3\xb9\xfe')返回{'encoding': 'GB2312', 'confidence': 0.99},但别在生产脚本里依赖自动检测——旧系统导出格式稳定,硬编码cp936更可靠 - 如果脚本要处理混合编码文件,优先按业务来源约定编码,而非尝试“智能识别”
真正麻烦的不是读取本身,而是后续字符串比较、正则匹配、数据库写入时仍按 GBK 逻辑处理——比如用 .encode('utf-8') 转存后,再用 re.search(r'张.*李', s) 就可能因编码混用漏匹配。保持全程统一编码意识,比找对第一个 encoding 参数重要得多。

















