【问题标题】:UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to <undefined>UnicodeDecodeError: \'charmap\' 编解码器无法解码位置 Y 中的字节 X:字符映射到 <undefined>
【发布时间】:2022-09-29 16:38:11
【问题描述】:

我正在尝试让 Python 3 程序对充满信息的文本文件进行一些操作。但是,在尝试读取文件时出现以下错误:

Traceback (most recent call last):  
   File "SCRIPT LOCATION", line NUMBER, in <module>  
     text = file.read()
   File "C:\Python31\lib\encodings\cp1252.py", line 23, in decode  
     return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 2907500: character maps to `<undefined>`  

【问题讨论】:

标签: python python-3.x unicode file-io decode


【解决方案1】:

有问题的文件未使用 CP1252 编码。它正在使用另一种编码。哪一个你必须自己弄清楚。常见的是Latin-1UTF-8。自从0x90Latin-1UTF-8中实际上没有任何意义(其中0x90是一个连续字节)更有可能。

打开文件时指定编码:

file = open(filename, encoding="utf8")

【讨论】:

  • 如果您使用的是 Python 2.7,并遇到同样的错误,请尝试 io 模块:io.open(filename,encoding="utf8")
  • +1 用于指定读取时的编码。附:它应该是 encoding="utf8" 还是 encoding="utf-8" ?
  • @1vand1ng0:Latin-1 当然可以;无论文件的实际编码是什么,它都适用于任何文件。这是因为文件中所有 256 个可能的字节值都有一个 Latin-1 代码点可以映射到,但这并不意味着您会得到清晰的结果!如果您不知道编码,即使以二进制模式打开文件也可能比假设使用 Latin-1 更好。
  • 即使编码已在 open() 中正确指定为 UTF-8(如上所示),我仍收到 OP 错误。有任何想法吗?
  • 建议的编码字符串应该有一个破折号,因此它应该是: open(csv_file, encoding='utf-8') (在 Python3 上测试过)
【解决方案2】:

如果file = open(filename, encoding="utf-8") 不起作用,请尝试
file = open(filename, errors="ignore"),如果你想删除不需要的字符。 (docs)

【讨论】:

  • 警告:当遇到未知字符时,这将导致数据丢失(根据您的情况,这可能没问题)。
【解决方案3】:

或者,如果您不需要解码文件,例如将文件上传到网站,请使用:

open(filename, 'rb')

在哪里r=,b=二进制

【讨论】:

  • 也许强调 b 将产生 bytes 而不是 str 数据。正如您所注意到的,如果您不需要以任何方式处理字节,这是合适的。
  • 前两个答案不起作用,但这个答案起作用了。我试图阅读 pandas 数据框的字典,但一直出错。
【解决方案4】:

作为@LennartRegebro's answer的扩展:

如果您不知道您的文件使用什么编码并且上面的解决方案不起作用(它不是utf8)并且您发现自己只是在猜测 - online tools 可以用来识别它是什么编码。它们并不完美,但通常工作得很好。找出编码后,您应该可以使用上面的解决方案。

编辑:(复制自评论)

一个非常流行的文本编辑器 Sublime Text 有一个命令来显示编码,如果它已经被设置...

  1. 转到View -> Show Console(或控制键+`)

    1. 在底部的字段中输入view.encoding()并希望最好(除了Undefined我什么也得不到,但也许你会有更好的运气......)

【讨论】:

  • 一些文本编辑器也会提供此信息。我知道使用 vim 你可以通过:set fileencoding (from this link)
  • Sublime Text,也——打开控制台并输入view.encoding()
  • 或者,您可以使用记事本打开文件。 “另存为”,您将看到一个包含所用编码的下拉列表
【解决方案5】:

TLDR:尝试:file = open(filename, encoding='cp437')

为什么?当一个人使用时:

file = open(filename)
text = file.read()

Python 假定该文件使用与当前环境相同的代码页(cp1252 在开头的帖子中)并尝试将其解码为它自己的默认值 UTF-8。如果文件包含此代码页中未定义值的字符(如 0x90),我们将得到 UnicodeDecodeError。有时我们不知道文件的编码,有时文件的编码可能未被 Python 处理(例如 cp790),有时文件可能包含混合编码。

如果不需要这些字符,可以决定用问号代替它们,即:

file = open(filename, errors='replace')

另一种解决方法是使用:

file = open(filename, errors='ignore')

这些字符将保持原样,但其他错误也将被屏蔽。

一个很好的解决方案是指定编码,但不是任何编码(如cp1252),而是定义了所有字符的编码(如cp437):

file = open(filename, encoding='cp437')

代码页 437 是原始的 DOS 编码。所有代码都已定义,因此在读取文件时没有错误,没有错误被屏蔽,字符被保留(不是完全完整,但仍然可以区分)。

【讨论】:

  • 也许您应该更加强调随机猜测编码可能会产生垃圾。你必须知道数据的编码。
  • 谢谢@rha。我也遇到了类似的错误。解决方案真的很有帮助。 <br/> > 部分错误:File C:UsersxxxAppDataLocalProgramsPythonPython310libencodingscp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 6675: character maps to &lt;undefined&gt;
【解决方案6】:
【解决方案7】:

对我来说,使用 utf16 编码有效

file = open('filename.csv', encoding="utf16")

【讨论】:

  • 与此页面上的许多其他答案一样,随机猜测 OP 实际处理的是哪种编码主要是浪费时间。正确的解决方案是告诉他们如何找出正确的编码,而不是提供更多的猜测(Python 文档包含所有这些的列表;还有很多很多,这里的任何答案都没有建议,但是可以对于任何随机访问者都是正确的)。 UTF-16 很烦人,因为如果您不会说这种语言,结果通常会模糊地看起来像是有效的中文或韩文文本。
【解决方案8】:

对于那些在 Windows 中使用 Anaconda 的人,我遇到了同样的问题。 Notepad++ 帮我解决了。

在 Notepad++ 中打开文件。在右下角,它会告诉你当前的文件编码。 在顶部菜单中,在“查看”旁边找到“编码”。在“编码”中转到“字符集”,然后耐心地寻找您需要的编码。在我的例子中,编码“Windows-1252”是在“Western European”下找到的

【讨论】:

  • 以这种方式仅更改了观看编码。为了有效地更改文件的编码,请更改 Notepad++ 中的首选项并创建一个新文档,如下所示:superuser.com/questions/1184299/…
【解决方案9】:

在应用建议的解决方案之前,您可以检查文件中(和错误日志中)出现的 Unicode 字符是什么,在本例中为 0x90https://unicodelookup.com/#0x90/1(或直接在 Unicode Consortium 站点 http://www.unicode.org/charts/ 上搜索0x0090)

然后考虑将其从文件中删除。

【讨论】:

  • 我在 tripleee.github.io/8bit/#90 有一个网页,您可以在其中查找 Python 支持的各种 8 位编码中的字符值。有了足够的数据点,您通常可以推断出合适的编码(尽管其中一些非常相似,因此建立确切地原作者使用的编码通常也会涉及一些猜测)。
【解决方案10】:

在较新版本的 Python(从 3.7 开始)中,您可以添加解释器选项-Xutf8,这应该可以解决您的问题。如果你使用 Pycharm,只需跑步>编辑配置(在选项卡配置更改字段中的值解释器选项-Xutf8)。

或者,等效地,您可以将环境变量 PYTHONUTF8 设置为 1。

【讨论】:

  • 这假定源数据是 UTF-8,这绝不是给定的。
【解决方案11】:
def read_files(file_path):

    with open(file_path, encoding='utf8') as f:
        text = f.read()
        return text

或(与)

def read_files(text, file_path):

    with open(file_path, 'rb') as f:
        f.write(text.encode('utf8', 'ignore'))

【讨论】:

    【解决方案12】:

    对我来说,更改与我的代码相同的 Mysql 字符编码有助于找出解决方案。 photo=open('pic3.png',encoding=latin1)

    【讨论】:

    • 与许多其他随机猜测一样,“latin-1”会消除错误,但不能保证文件被正确解码。你必须知道文件的编码实际上使用。另请注意,不带引号的 latin1 是一个语法错误(除非您有一个具有该名称的变量,并且它包含一个表示有效 Python 字符编码名称的字符串)。
    • 在此特定示例中,真正的问题是 PNG 文件根本不包含文本。您应该改为读取原始字节(open('pic3.png', 'rb'),其中 b 表示二进制模式)。
    猜你喜欢
    • 2019-06-01
    • 2012-03-03
    • 1970-01-01
    • 2018-09-13
    • 2017-08-12
    • 2019-10-20
    • 2017-02-06
    相关资源
    最近更新 更多