UnicodeEncodeError:'charmap'编解码器无法编码字符
- 2024-11-27 10:43:00
- admin 原创
- 17
问题描述:
我正在尝试抓取一个网站,但它给出了一个错误。
我正在使用以下代码:
import urllib.request
from bs4 import BeautifulSoup
get = urllib.request.urlopen("https://www.website.com/")
html = get.read()
soup = BeautifulSoup(html)
我收到了以下错误:
File "C:Python34libencodingscp1252.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>
我该如何修复此问题?
解决方案 1:
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
。
解决方案 2:
我通过添加来修复此.encode("utf-8")
问题soup
。
这意味着print(soup)
变成print(soup.encode("utf-8"))
。
解决方案 3:
在 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 字符时返回错误。
解决方案 4:
set PYTHONIOENCODING=utf-8
set PYTHONLEGACYWINDOWSSTDIO=utf-8
您可能需要或不需要设置第二个环境变量PYTHONLEGACYWINDOWSSTDIO
。
或者,这也可以在代码中完成(尽管似乎建议通过环境变量来完成):
sys.stdin.reconfigure(encoding='utf-8')
sys.stdout.reconfigure(encoding='utf-8')
此外: 重现这个错误有点麻烦,因此也请将其留在这里,以防您需要在您的机器上重现它:
set PYTHONIOENCODING=windows-1252
set PYTHONLEGACYWINDOWSSTDIO=windows-1252
解决方案 5:
在保存 get 请求的响应时,Windows 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)
解决方案 6:
甚至我在尝试打印、读取/写入或打开它时也遇到了同样的编码问题。正如上面其他人提到的,如果您尝试打印它,添加 .encoding="utf-8" 会有所帮助。
汤.编码(“utf-8”)
如果您尝试打开抓取的数据并将其写入文件,则使用 (......,encoding="utf-8") 打开该文件
使用 open(filename_csv,'w',newline='',encoding="utf-8") 作为 csv_file:
解决方案 7:
这个问题涉及多个方面。最根本的问题是要输出到哪个字符集。您可能还必须弄清楚输入字符集。
使用print
或write
显式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 服务器和后端数据库之间的连接。请参阅使用正确字符编码(python 请求 + beautifulsoup)抓取,获取包含一些解决方案的更详细示例。
您要写入的字符集是什么?如果打印到屏幕上,您的终端是否配置正确,并且您的 Python 解释器是否配置相同?或许还可以参阅如何在 Windows 控制台中显示 utf-8
如果您在这里,那么这些问题之一的答案可能不是“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ö
。
如果字符数据的编码未知,则没有简单的方法可以自动建立它。如果您知道文本应该表示什么,您也许可以推断它,但这通常是一个手动过程,需要一些猜测。(像chardet
和这样的自动工具ftfy
可以提供帮助,但它们有时也会出错。)
要确定您正在查看的编码,如果您可以识别未正确显示的字符中的各个字节,这将很有帮助。例如,如果您正在查看Hx8ellx9a
但希望它表示Héllö
,您可以在转换表中查找字节。我在https://tripleee.github.io/8bit上发布了一个这样的表,您可以在其中看到,在这个例子中,它可能是传统的 Mac 8 位字符集之一;有了更多的数据点,也许您可以将其缩小到其中之一(如果不是,实际上其中任何一个都可以,因为您关心的所有代码点都映射到相同的 Unicode 字符)。
大多数平台上的 Python 3 默认所有输入和输出都使用 UTF-8,但在 Windows 上,情况通常并非如此。它会改为默认使用系统的默认编码(在某些 Microsoft 文档中,仍被误导性地称为“ANSI 代码页”),这取决于许多因素。在西方系统上,开箱即用的默认编码通常是 Windows 代码页 1252。(早期的 Python 版本对此有不同的期望,而在 Python 2 中,内部字符串表示不是 Unicode。)
如果您在 Windows 上将 UTF-8 写入文本文件,则可能需要指定encoding="utf-8-sig"
在文件开头添加 BOM 序列。严格来说,这不是必需的或正确的,但某些 Windows 工具需要它来正确识别编码。
这里之前的几个答案建议盲目地应用某种编码,但希望这可以帮助您理解这通常不是正确的方法,以及如何找出(而不是猜测)要使用哪种编码。
解决方案 8:
对于仍然遇到此错误的人,添加encode("utf-8")
也soup
将修复此问题。
soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
解决方案 9:
从 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
来源
解决方案 10:
我遇到了同样的错误,所以我使用 (encoding="utf-8") 并解决了错误。这通常发生在我们在文本数据中得到一些我们的编码器无法理解的未识别符号或模式时。
with open("text.txt", "w", encoding='utf-8') as f:
f.write(data)
这将解决你的问题。
解决方案 11:
如果您使用的是 Windows,请尝试传递encoding='latin1'、encoding='iso-8859-1' 或 encoding='cp1252'
示例:
csv_data = pd.read_csv(csvpath,encoding='iso-8859-1')
print(print(soup.encode('iso-8859-1')))
解决方案 12:
修复了我的错误并添加.content.decode("utf-8")
到我的回复中...之前对这个问题的回答比如.encode("utf-8")
在末尾添加;对我来说不起作用,因为在我的代码中我需要.find_all()
在修复我的编码错误后使用...
代码如下:
import request
from bs4 import BeautifulSoup
get = request("https://www.website.com/")
html = get.content.decode("utf-8")
soup = BeautifulSoup(html, "html.parser")
#your code
soup.find_all(name="h3")
解决方案 13:
将以下内容添加到脚本顶部:
# Fix UnicodeEncodeError: 'charmap' codec can't encode characters
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
直接编码虽然sys.stdout
能解决一些问题,但也存在一些不足,不是最佳实践。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件