UnicodeEncodeError: & # 39; charmap& # 39;编解码器不能编码字符

我试图抓取一个网站,但它给了我一个错误。

我正在使用以下代码:

import urllib.request
from bs4 import BeautifulSoup


get = urllib.request.urlopen("https://www.website.com/")
html = get.read()


soup = BeautifulSoup(html)


print(soup)

我得到以下错误:

File "C:\Python34\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 70924-70950: character maps to <undefined>

我该怎么补救呢?

841070 次浏览

我通过将.encode("utf-8")添加到soup来修复它。

这意味着print(soup)变成了print(soup.encode("utf-8"))

对于那些仍然得到此错误的人,将encode("utf-8")添加到soup也将修复此问题。

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)

我得到相同的UnicodeEncodeError时,保存抓取的网页内容到一个文件。为了修复它,我替换了以下代码:

with open(fname, "w") as f:
f.write(html)

用这个:

with open(fname, "w", encoding="utf-8") as f:
f.write(html)

如果你需要支持Python 2,那么使用这个:

import io
with io.open(fname, "w", encoding="utf-8") as f:
f.write(html)

如果你想使用不同于UTF-8的编码,为encoding指定你的实际编码。

在Python 3.7中,并运行Windows 10,这是可行的(我不确定它是否适用于其他平台和/或其他版本的Python)

替换这一行:

with open('filename', 'w') as f:

用这个:

with open('filename', 'w', encoding='utf-8') as f:

之所以能正常工作,是因为在使用该文件时,编码被更改为UTF-8,因此UTF-8中的字符能够转换为文本,而不是在遇到当前编码不支持的UTF-8字符时返回错误。

在保存get请求的响应时,在窗口10的Python 3.7上抛出了相同的错误。从URL接收到的响应,编码是UTF-8,所以总是建议检查编码,这样就可以传递相同的编码,以避免这种琐碎的问题,因为它真的在生产中浪费了大量的时间

import requests
resp = requests.get('https://en.wikipedia.org/wiki/NIFTY_50')
print(resp.encoding)
with open ('NiftyList.txt', 'w') as f:
f.write(resp.text)

当我用open命令添加encoding="utf-8"时,它会以正确的响应保存文件

with open ('NiftyList.txt', 'w', encoding="utf-8") as f:
f.write(resp.text)

即使是我也面临着同样的编码问题,当你试图打印它,读/写它或打开它时。正如上面提到的,如果你想打印它,添加.encoding="utf-8"会有帮助。

soup.encode(“utf - 8”)

如果您试图打开抓取的数据并可能将其写入文件,则使用(......,encoding="utf-8")打开该文件

open(filename_csv, 'w', newline= ",encoding="utf-8") as csv:

如果您正在使用Windows,请尝试传递encoding='latin1', encoding='iso-8859-1'或encoding='cp1252' 例子:< / p >

csv_data = pd.read_csv(csvpath,encoding='iso-8859-1')
print(print(soup.encode('iso-8859-1')))
set PYTHONIOENCODING=utf-8
set PYTHONLEGACYWINDOWSSTDIO=utf-8

你可能需要也可能不需要设置第二个环境变量PYTHONLEGACYWINDOWSSTDIO

或者,这可以在代码中完成(尽管似乎建议通过env vars来完成):

sys.stdin.reconfigure(encoding='utf-8')
sys.stdout.reconfigure(encoding='utf-8')

另外: 重现此错误有点麻烦,所以把这个也留在这里,以防你需要在你的机器上复制它:

set PYTHONIOENCODING=windows-1252
set PYTHONLEGACYWINDOWSSTDIO=windows-1252

这个问题有很多方面。最基本的问题是您希望输出到哪个字符集。您可能还必须找出输入字符集。

将(使用printwrite)打印到带有显式encoding="..."的文件中将Python内部的Unicode表示转换为该编码。如果输出包含该编码不支持的字符,则将得到UnicodeEncodeError。例如,你不能写俄语、中文、印度语、希伯来语、阿拉伯语、表情符号或……除了200多个西方字符的限制集之外,任何东西都可以转换到编码为"cp1252"的文件中,因为这个有限的8位字符集无法表示这些字符。

基本上,任何8位字符集都会出现同样的问题,包括几乎所有的传统Windows代码页(437、850、1250、1251等),尽管其中一些代码页除了支持或取代英语,还支持一些额外的脚本(例如,1251支持西里尔字母,所以你可以写俄语、乌克兰语、塞尔维亚语、保加利亚语等)。8位编码最多只能有256个字符代码,并且无法表示不在其中的字符。

也许现在是阅读Joel Spolsky的每个软件开发人员必须绝对、肯定地了解Unicode和字符集(没有借口!)的好时机

在终端无法打印Unicode的平台上(现在只有Windows,不过如果你喜欢回溯计算,这个问题在上个千年的其他平台上也很普遍),尝试print Unicode字符串也会产生这个错误,或输出mojibake。如果你看到的是Héllö而不是Héllö,这就是你的问题。

简而言之,你需要知道:

  • 你抓取的页面的字符集是什么,或者你收到的数据是什么?刮对了吗?发起者是否正确地识别了它的编码,或者您是否能够以其他方式获得该信息(或猜测它)?有些网站错误地声明了与页面实际包含的字符集不同的字符集,有些网站错误地配置了web服务器和后端数据库之间的连接。有关一些解决方案的更详细示例,请参阅e.g. 使用正确的字符编码(python requests + beautifulsoup)

  • 你想写的字符集是什么?如果打印到屏幕上,您的终端配置是否正确,并且Python解释器配置是否相同? 也许还可以参见如何显示utf-8在windows控制台

如果你在这里,可能其中一个问题的答案不是“utf -8”。这也越来越成为网页的普遍编码,尽管以前的标准是ISO-8859-1(又名Latin-1),最近是Windows代码页1252。

接下来,除了少数边缘用例外,您基本上希望所有文本数据都是Unicode。通常,这意味着UTF-8,尽管在Windows上(或者如果您需要Java兼容性),UTF-16也是模糊可行的,尽管有点麻烦。(还有其他几种Unicode序列化格式,在特殊情况下可能很有用。UTF-32在技术上是微不足道的,但是占用了更多的内存;UTF-7在一些需要7位ASCII进行传输的网络协议中使用。) 也许还可以参见https://utf8everywhere.org/

当然,如果要打印到文件中,还需要使用能够正确显示该文件的工具来检查该文件。常见的引导错误是使用只显示当前选择的系统编码的工具打开文件,或者使用试图猜测编码但猜错的工具。同样,在使用Windows代码页1252查看UTF-8文本时,一个常见的症状会导致,例如,Héllö显示为Héllö

如果字符数据的编码是未知的,就没有简单的方法来自动建立它。如果您知道文本应该表示什么,您也许可以推断出它,但这通常是一个手工过程,涉及到一些猜测。(自动工具如chardetftfy可以提供帮助,但它们有时也会出错。)

为了确定您正在查看的编码,如果您能够识别字符中没有正确显示的单个字节,则会很有帮助。例如,如果你正在查看H\x8ell\x9a,但希望它表示Héllö,你可以在翻译表中查找字节。我已经在https://tripleee.github.io/8bit中发布了一个这样的表,在这个例子中,你可以看到,它可能是一个传统的Mac 8位字符集;如果有更多的数据点,也许可以将其缩小到其中一个(如果不能,实际上任何一个都可以,因为您关心的所有代码点都映射到相同的Unicode字符)。

Python 3在大多数平台上的所有输入和输出默认为UTF-8,但在Windows上,通常不是这样。然后它将改为默认系统的默认编码(仍然被误导地称为“ANSI代码页”);在一些微软文档中),这取决于许多因素。在西方系统中,默认的开箱编码通常是Windows代码页1252。 (早期的Python版本有不同的期望,在Python 2中,内部字符串表示不是Unicode。)

如果你在Windows上并将UTF-8写入一个文本文件,可能会指定encoding="utf-8-sig",它会在文件的开头添加一个BOM序列。严格来说,这是不必要或不正确的,但一些Windows工具需要它来正确识别编码。

前面的几个回答建议盲目地应用某种编码,但希望这能帮助您理解为什么这通常不是正确的方法,以及如何找出(而不是猜测)要使用哪种编码。

从Python 3.7开始, 将环境变量PYTHONUTF8设置为1

下面的脚本还包括其他有用的变量,用于设置系统环境变量。

setx /m PYTHONUTF8 1
setx PATHEXT "%PATHEXT%;.PY" ; In CMD, Python file can be executed without extesnion.
setx /m PY_PYTHON 3.10 ; To set default python version for py

< a href = " https://dev。to/methane/python-use-utf-8-mode-on-windows-212i" rel="nofollow noreferrer">来源 . txt

我得到了同样的错误,所以我使用(encoding="utf-8"),它解决了错误。 这通常发生在我们的编码器不理解的文本数据中一些未识别的符号或模式时

with open("text.txt", "w", encoding='utf-8') as f:
f.write(data)

这将解决你的问题。