UnicodeEncodeError:'charmap'编解码器无法编码字符

Sst*_*erR 152 python urllib beautifulsoup

我正在试图抓一个网站,但它给了我一个错误.

我正在使用以下代码:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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>
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能解决这个问题?

twa*_*lig 169

UnicodeEncodeError将抓取的Web内容保存到文件时,我的情况也是如此.要解决它,我替换了这段代码:

with open(fname, "w") as f:
    f.write(html)
Run Code Online (Sandbox Code Playgroud)

有了这个:

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

使用io使您可以向后兼容Python 2.

如果您只需要支持Python 3,则可以使用内置open函数:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)
Run Code Online (Sandbox Code Playgroud)

  • 在mac(python 3)中,只需打开而不进行编码就可以完美地工作,但是在windows(w10,python3)中不是一个选项.只是以这种方式工作,使用encoding ="utf-8"param. (4认同)
  • 谢谢.它对我有用,我正在使用xml文件并将xml.toprettyxml()的结果写入一个新文件 (3认同)
  • 这应该是公认的答案,因为它最终会向输出写入一个字符串,而不是字节的字符串表示。 (2认同)
  • 然而,OP 请求读取文件,而不是写入文件。该问题似乎与控制台有关。 (2认同)

Sst*_*erR 162

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

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

  • 这使它打印出 `b'\x02x\xc2\xa9'`(一个字节对象) (4认同)
  • 我使用了上面的解决方案,但仍然遇到问题: class MyStreamListener(tweepy.StreamListener): def on_status(self, status): print(str(status.encode("utf-8"))) UnicodeEncodeError: 'charmap' codec can' t 在位置 87 编码字符 '\u2019':字符映射到 &lt;undefined&gt; (3认同)
  • 不要在脚本中硬编码环境的字符编码(例如,控制台),[直接打印Unicode](http://stackoverflow.com/a/32176732/4279) (2认同)
  • 这只是打印一个 `bytes` 对象的 repr,如果有很多 UTF-8 编码的文本,它将打印为一堆 `\x` 序列。我建议使用`win_unicode_console`,正如@JFSebastian 所建议的那样。 (2认同)
  • `print(soup.encode("utf-8"))` 对我有用,但在此之前我还必须添加 `with open("f_name",encoding="utf-8") as f: soup = BeautifulSoup( f, "html.parser")` (2认同)

Sab*_*med 27

在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字符时返回错误不受当前编码的支持.

  • 打印(汤)返回\xd0\xbf\xd0\xbe\xd0\xb6\xd0\xb0\xd0\xbb\xd1\x83\xd0\xb9\xd (3认同)

Voy*_*Voy 22

set PYTHONIOENCODING=utf-8
set PYTHONLEGACYWINDOWSSTDIO=utf-8
Run Code Online (Sandbox Code Playgroud)

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

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

sys.stdin.reconfigure(encoding='utf-8')
sys.stdout.reconfigure(encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)

另外: 重现这个错误有点痛苦,所以把它留在这里以防你需要在你的机器上重现它:

set PYTHONIOENCODING=windows-1252
set PYTHONLEGACYWINDOWSSTDIO=windows-1252
Run Code Online (Sandbox Code Playgroud)

  • 在 Windows 10 上,使用 GIT BASH 设置上述环境变量不起作用,但是,在实际的 python 代码文件中设置两行确实起作用: `sys.stdin.reconfigure(encoding='utf-8') sys.stdin.reconfigure(encoding='utf-8') sys.stdin.reconfigure(encoding='utf-8') stdout.reconfigure(编码='utf-8')` (8认同)
  • `sys.stdin.reconfigure` 在 Python 3.9.0 上无效,它会抛出 `AttributeError: 'StdInputFile' 对象没有属性 'reconfigure'` (3认同)

Abh*_*ain 9

在保存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)
Run Code Online (Sandbox Code Playgroud)

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

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


小智 7

甚至我在尝试打印,读取/写入或打开它时都遇到与编码相同的问题。如上述其他提到的那样,如果您尝试打印.encoding =“ utf-8”,则将有所帮助。

soup.encode(“ utf-8”)

如果您尝试打开抓取的数据并将其写入文件,请使用(......,encoding =“ utf-8”)打开文件

使用open(filename_csv,'w',newline ='',encoding =“ utf-8”)作为csv_file:


Pse*_*udo 6

对于那些仍然收到此错误,添加encode("utf-8")soup也将解决这个问题。

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
Run Code Online (Sandbox Code Playgroud)

  • 执行此操作后,“soup”不再是“BeautifulSoup”对象,因此无法对其进行操作或搜索 (9认同)

tri*_*eee 5

这个问题有多个方面。根本问题是您想要输出到哪个字符集。您可能还需要弄清楚输入字符集。

\n

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

\n

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

\n

也许现在是阅读 Joel Spolsky 的《每个软件开发人员绝对必须了解 Unicode 和字符集的绝对最低要求(没有借口!)》的好时机。

\n

在终端无法打印 Unicode 的平台上(实际上只有 Windows,但如果您进行逆向计算,这个问题在上个世纪的其他平台上也很普遍)尝试使用printUnicode 字符串也可能会产生此错误,或输出mojibake。如果您看到类似H\xc3\x83\xc2\xa9ll\xc3\x83\xc2\xb6而不是 的内容H\xc3\xa9ll\xc3\xb6,则这是您的问题。

\n

简而言之,您需要知道:

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

    \n
  • \n
  • 你想写的字符集是什么?如果打印到屏幕,您的终端配置是否正确,Python 解释器配置是否相同?\n也许另请参阅如何在 Windows 控制台中显示 utf-8

    \n
  • \n
\n

如果您在这里,这些问题之一的答案可能不是“UTF-8”。尽管以前的标准是 ISO-8859-1(又名 Latin-1),最近的标准是 Windows 代码页 1252,但这也日益成为网页的流行编码。

\n

展望未来,除了一些边缘用例之外,您基本上希望所有文本数据都是 Unicode。一般来说,这意味着 UTF-8,尽管在 Windows 上(或者如果您需要 Java 兼容性),UTF-16 也隐约可行,尽管有点麻烦。(还有其他几种 Unicode 序列化格式,在特殊情况下可能很有用。UTF-32 在技术上很简单,但占用更多内存;UTF-7 用于一些需要 7 位 ASCII 的网络协议运输。)\n也许另请参阅https://utf8everywhere.org/

\n

当然,如果您要打印到文件,您还需要使用可以正确显示该文件的工具来检查该文件。一个常见的试点错误是使用仅显示当前选定的系统编码的工具打开文件,或者使用尝试猜测编码但猜测错误的工具打开文件。同样,使用 Windows 代码页 1252 查看 UTF-8 文本时的常见症状可能会导致显示H\xc3\xa9ll\xc3\xb6H\xc3\x83\xc2\xa9ll\xc3\x83\xc2\xb6.

\n

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

\n

要确定您正在查看的编码,如果您可以识别未正确显示的字符中的各个字节,则会很有帮助。例如,如果您正在查看H\\x8ell\\x9a但希望它表示H\xc3\xa9ll\xc3\xb6,则可以在转换表中查找字节。我在https://tripleee.github.io/8bit上发布了一张这样的表,您可以在这个示例中看到,它可能是旧版 Mac 8 位字符集之一;如果有更多数据点,也许您可​​以将范围缩小到其中一个(如果没有,则实际上可以使用其中任何一个,因为您关心的所有代码点都映射到相同的 Unicode 字符)。

\n

大多数平台上的 Python 3 默认使用 UTF-8 进行所有输入和输出,但在 Windows 上,情况通常并非如此。然后,它将默认为系统的默认编码(在某些 Microsoft 文档中仍然被误导性地称为“ANSI 代码页”),这取决于许多因素。在西方系统上,开箱即用的默认编码通常是 Windows 代码页 1252。\n(早期的 Python 版本有一些不同的期望,在 Python 2 中,内部字符串表示形式不是 Unicode。)

\n

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

\n

这里的一些早期答案建议盲目地应用一些编码,但希望这可以帮助您理解这通常不是正确的方法,以及如何弄清楚(而不是猜测)要使用哪种编码。

\n