尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

一招解决Python编码乱码难题

一招解决Python编码乱码难题 一碰到这种情况就感到心里发慌? 那么这篇内容就可以帮助你把它处理得妥妥当当。你肯定遇到过这个报错 with open(data.txt, r) as f:... content f.read()...UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 2: illegal multibyte sequence一瞬间就让人感到非常困惑, 那个文件明明是可以正常打开的, 可是为什么却无法被读取呢?其答案非常简单: 那是因为编码不匹配先搞懂什么是编码计算机它只管认识那个零和这个一, 然后在文件里面摆放的那些文字呢, 它们实际上都是那种经过了编码处理过的数据形式, 而且这种数据的形式就是二进制的。你好 → 编码器 → 011001011101... → 存到文件011001011101... → 解码器 → 你好显示在屏幕编码的操作和解码的操作都必须使用相同的一个规则来进行, 如果使用的规则不一样, 那么结果就会变成无法识别的乱码。记事本这个软件, 它在默认的场合下是使用 GBK 的, VS Code 这个软件,它在默认的场合下是使用 UTF-8 的, 就是因为有这么个分别, 所以导致了各种乱码的现象出现, 这这就是造成这种情况的根本原因所在。一招解决90%的编码问题# 记住这行解决90%问题with open(data.txt, r, encodingutf-8) as f:content f.read()事情就是这么简单在调用 open() 这个方法的时候, 直接把参数设置为 utf-8 就行了。问题是, 如果该文件所使用的编码格式并不是UTF-8, 那该怎么办呢?万能应对方案: 针对方案一的情况, 选择一种做法, 也就是试着一个一个地对编码进行尝试。def read_file_safe(filename):encodings [utf-8, gbk, gb2312, gb18030, latin-1]for enc in encodings:try:with open(filename, r, encodingenc) as f:return f.read()except UnicodeDecodeError:continueraise Exception(f无法解码文件{filename})# 使用content read_file_safe(未知编码的文件.txt)print(f读取成功共{len(content)}个字符)推荐的是方案二, 也就是对文件的编码形式来进行检测。安装一个非常厉害的小工具, 这个操作很简单, 只需要输入一行命令代码就可以完成安装了。pip install chardetimport chardet# 检测文件编码with open(data.txt, rb) as f:raw f.read(10000) # 读取前10000字节就够了result chardet.detect(raw)print(result)# 输出示例{encoding: utf-8, confidence: 0.99, language: }# 用检测结果打开encoding result[encoding]with open(data.txt, r, encodingencoding) as f:content f.read()它用来表示置信度。当数值是0.99的时候, 就是指有99%的把握确定这就是那个编码。我们来看看方案3, 这个方案采用的是Latin-1编码作为保底的处理方法。# latin-1不会报错但中文会变成乱码# 只能作为最最后的保底方案with open(data.txt, r, encodinglatin-1) as f:content f.read()写入时的编码我们在书写文件的过程中, 也需要留意编码方面要保持一致的情况。# 不指定编码——Windows下用默认编码GBKwith open(output.txt, w) as f:f.write(中文) # Windows存成了GBK# 指定编码——明确使用UTF-8with open(output.txt, w, encodingutf-8) as f:f.write(中文) # 明确存成UTF-8# 这样其他人在mac/Linux上也能正常读取在实际的操作过程中, 我们可以使用编码转换工具。def convert_encoding(src_file, dst_file, src_encgbk, dst_encutf-8):转换文件编码try:with open(src_file, r, encodingsrc_enc) as f:content f.read()with open(dst_file, w, encodingdst_enc) as f:f.write(content)print(f 编码转换完成{src_enc} → {dst_enc})except Exception as e:print(f 转换失败{e})# 把GBK文件转成UTF-8convert_encoding(old_gbk_file.txt, new_utf8_file.txt)中常见的编码错误及解决错误信息原因解决方法解码时编码不匹配指定正确的编码编码时字符超出范围用: Non-UTF-8 code那个原文件, 它里面是没有包含UTF-8这个编码方式的。文件头部加代码文件的编码设置为 utf-8。关于参数的详细解释。# strict —— 默认遇到错误直接报错with open(data.txt, r, encodingutf-8, errorsstrict) as f:pass# ignore —— 忽略错误字符with open(data.txt, r, encodingutf-8, errorsignore) as f:content f.read() # 坏字符被直接丢弃# replace —— 用替代字符替换with open(data.txt, r, encodingutf-8, errorsreplace) as f:content f.read() # 坏字符变成 # backslashreplace —— 转义显示with open(data.txt, r, encodingutf-8, errorsbackslashreplace) as f:content f.read() # 坏字符显示为 \x??在各个不相同的平台里, 默认采用的编码方式各有差异。import sys# 查看当前系统的默认编码print(f默认编码{sys.getdefaultencoding()})print(f文件系统编码{sys.getfilesystemencoding()})# Windows输出默认编码utf-8Python3文件系统编码utf-8# 但是文件操作的默认编码在Windows上是GBK这正是问题的关键所在, 因为内部使用的是UTF-8编码格式, 但是在打开文件的时候, 系统默认采用的是GBK编码方式。因此, 我们必须要显式地指定 utf-8。终极建议是: 在读写文件的时候, 都要加上utf-8参数, 把这个习惯练成肌肉记忆。自己写的文件, 一律使用UTF-8编码。这样做是跨平台最友好的方式。处理别人给的文件时, 先用方法检测编码。在源文件的头部加上 -*- : utf-8 -*-这一行代码, 老项目需要这样设置, 默认情况下已经是UTF-8了。你遇到过什么样的、让人感觉最为糟糕的编码方面的问题? 这些情况是, 因为使用Excel导出导致文本变成乱码, 或者是利用爬虫程序去下载那些使用GBK编码格式的网页所引发的错误。请在我们的评论区当中详细叙述你所经历的相关故事。
返回列表