UnicodeDecodeError:'charmap'编解码器无法解码位置Y的字节X:字符映射到<undefined>


549

我正在尝试让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>`  

2
对于相同的错误,这些解决方案对我有帮助,charmap错误的解决方案
Shubham Sharma

2
请参阅在Python 3中处理文本文件以了解为什么会出现此错误。
安德烈亚斯·哈弗堡

Answers:


958

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

您在打开文件时指定编码:

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

19
太酷了,我遇到了一些我尝试在Python 3.4中运行的Python 2.7代码的问题。Latin-1为我工作!
1vand1ng0 2015年

2
如果您使用的是Python 2.7,并且遇到相同的错误,请尝试以下io模块:io.open(filename,encoding="utf8")
christopherlovell 2015年

9
@ 1vand1ng0:当然是Latin-1作品;它适用于任何文件,无论文件的实际编码是什么。那是因为文件中所有256个可能的字节值都有一个Latin-1代码点要映射,但这并不意味着您得到清晰的结果!如果您不知道编码,即使以二进制模式打开文件也可能比假设Latin-1更好。
马丁·彼得斯

1
默认情况下为unicode,但unicode不是编码。 regebro.wordpress.com/2011/03/23/...
伦纳特Regebro

1
filename = "C:\Report.txt" with open(filename,encoding ="utf8") as my_file: text = my_file.read() print(text)即使使用此后,我也遇到同样的错误。我也尝试了其他编码,但都没有用。在此代码中,我也使用from geotext import GeoText。请提出解决方案。
萨拉赫

47

只是添加以防万一file = open(filename, encoding="utf8")不起作用尝试file = open(filename, errors='ignore')


非常感谢-我会尝试的。我不关心文件的某些部分中存在一些无效字符。
Stephen Nutt

6
警告:遇到未知字符时,这将导致数据丢失(根据您的情况可能会很好)。
汉斯·戈德曼

34

作为@LennartRegebro答案的扩展:

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

编辑:(从评论中复制)

一个非常流行的文本编辑器Sublime Text有一个命令来显示编码(如果已设置)。

  1. 转到View-> Show Console(或Ctrl+ `

在此处输入图片说明

  1. 在底部输入字段,view.encoding()并希望获得最好的成绩(我什么也没得到,Undefined但也许您会有更好的运...)

在此处输入图片说明


2
一些文本编辑器也将提供此信息。我知道,通过vim,您可以通过:set fileencoding从此链接)获得此信息
PaxRomana99 2013年

3
也可以使用Sublime Text,打开控制台并输入view.encoding()
JimmidyJoo'7

或者,您可以使用记事本打开文件。“另存为”,您将看到一个使用编码的下拉列表
don_Gunner94


6

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编码。所有代码均已定义,因此在读取文件时没有错误,没有错误被掩盖,字符得以保留(不是很完整,但仍可区分)。


1
哇,真想你 这是对我唯一的解码作品。
科瓦尔斯基

1

对于那些在Windows的Anaconda中工作的人,我遇到了同样的问题。Notepad ++可以帮助我解决它。

在记事本++中打开文件。在右下角,它将告诉您当前的文件编码。在顶部菜单中,在“视图”旁边找到“编码”。在“编码”中,转到“字符集”,然后耐心地寻找所需的编码。在我的情况下,在“西欧”下找到了编码“ Windows-1252”


1

别再浪费时间了,只需将以下内容encoding="cp437"和内容添加errors='ignore'到读写中即可:

open('filename.csv', encoding="cp437", errors='ignore')
open(file_name, 'w', newline='', encoding="cp437", errors='ignore')

神速


先生 收到。没有时间浪费。谢谢。您要喝杯咖啡还是上等葡萄酒?
Pramesh Bajracharya

0

对我来说,更改与我的代码相同的Mysql字符编码有助于解决问题。photo = open('pic3.png',encoding = latin1), 强文本 在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.