【问题标题】:UnicodeEncodeError: 'charmap' codec can't encode charactersUnicodeEncodeError:“charmap”编解码器无法编码字符
【发布时间】:2015-01-21 10:57:36
【问题描述】:

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

我正在使用以下代码:

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>

我能做些什么来解决这个问题?

【问题讨论】:

    标签: python beautifulsoup urllib


    【解决方案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 的实际编码。

    【讨论】:

    • 在 mac(python 3) 中,只需要打开而无需编码即可完美运行,但在 windows(w10, python3) 中不是一个选项。以这种方式工作,使用 encoding="utf-8" 参数。
    • 谢谢。它对我有用,我正在处理 xml 文件并将 xml.toprettyxml() 的结果写入一个新文件
    • 这应该是公认的答案,因为它最终会将字符串写入输出,而不是字节的字符串表示形式。
    • OP 请求读取文件,但不写入文件。这个问题似乎与控制台有关。
    • 这行得通。但是你不必使用io,你所要做的就是在open函数中包含encoding="utf-8"
    【解决方案2】:

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

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

    【讨论】:

    • 不要在脚本中对环境(例如控制台)的字符编码进行硬编码,print Unicode directly instead
    • 这只是打印一个bytes 对象的repr,如果有很多UTF-8 编码的文本,它将打印成一堆\x 序列。正如@J.F.Sebastian 建议的那样,我建议使用win_unicode_console。
    • 我使用了上述解决方案,但仍然遇到问题:class MyStreamListener(tweepy.StreamListener): def on_status(self, status): print(str(status.encode("utf-8"))) UnicodeEncodeError:“charmap”编解码器无法在位置 87 编码字符“\u2019”:字符映射到
    • 这使它打印出b'\x02x\xc2\xa9'(一个字节对象)
    • print(soup.encode("utf-8")) 为我工作,但在此之前我还必须添加 with open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
    【解决方案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时返回错误当前编码不支持的字符。

    【讨论】:

    • 打印(汤)返回 \xd0\xbf\xd0\xbe\xd0\xb6\xd0\xb0\xd0\xbb\xd1\x83\xd0\xb9\xd
    【解决方案4】:
    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
    

    【讨论】:

    • 这是完美的;我在 Windows 系统上使用 Python 调试器 (pdb) 查看使用 utf-8 并包含大量表情符号的源代码时遇到此错误。每次我执行“list”命令查看我在哪里时,都会出现“charmap”错误。设置这两个环境变量让我的调试如丝般顺滑。
    • sys.stdin.reconfigure 在 Python 3.9.0 上无效,它会抛出 AttributeError: 'StdInputFile' object has no attribute 'reconfigure'
    • 在 Windows 10 上,使用 GIT BASH,设置上述环境变量不起作用,但是,在实际的 python 代码文件中设置两行 DID 工作:sys.stdin.reconfigure(encoding='utf-8') sys.stdout.reconfigure(encoding='utf-8')
    • @Suncatcher 尝试在不同的 IDE 中运行这个 Python 脚本
    • @PetrL。为什么我应该使用 IDE?所有有效的 Python 命令都应该在 Python Shell 中可解释,否则它们无效
    【解决方案5】:

    在保存 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)
    

    【讨论】:

      【解决方案6】:

      即使我在尝试打印、读/写或打开它时也遇到了同样的编码问题。正如上面提到的其他人所提到的,如果您尝试打印它,添加 .encoding="utf-8" 会有所帮助。

      soup.encode("utf-8")

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

      将 open(filename_csv , 'w', newline='',encoding="utf-8") 作为 csv_file:

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

        • soup 在您执行此操作后不再是 BeautifulSoup 对象,因此无法对其进行操作或搜索
        【解决方案8】:

        如果您使用的是 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')))
        

        【讨论】:

        • 有道理!如果我使用 utf-8 而不是 cp1252,你认为会发生什么?
        猜你喜欢
        • 2018-08-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多