Python 3 时来自 BeautifulSoup 的“非法多字节序列”错误

Posted

技术标签:

【中文标题】Python 3 时来自 BeautifulSoup 的“非法多字节序列”错误【英文标题】:"illegal multibyte sequence" error from BeautifulSoup when Python 3 【发布时间】:2020-02-06 13:15:23 【问题描述】:

.html 保存到本地磁盘,我正在使用 BeautifulSoup (bs4) 来解析它。

一切正常,直到最近它改为 Python 3。

我在另一台机器 Python 2 中测试了相同的 .html 文件,它可以工作并返回页面内容。

soup = BeautifulSoup(open('page.html'), "lxml")

使用 Python 3 的机器不起作用,它说:

UnicodeDecodeError: 'gbk' codec can't decode byte 0x92 in position 298670: illegal multibyte sequence

四处搜索,我在下面尝试过,但都没有成功:(无论是“r”还是“rb”都没有太大区别)

soup = BeautifulSoup(open('page.html', 'r'), "lxml")
soup = BeautifulSoup(open('page.html', 'r'), 'html.parser')
soup = BeautifulSoup(open('page.html', 'r'), 'html5lib')
soup = BeautifulSoup(open('page.html', 'r'), 'xml')

如何使用 Python 3 解析这个 html 页面?

谢谢。

【问题讨论】:

听起来 HTML 可能声明了错误的编码。不过,我不知道你会如何覆盖它。 当您说open('page.html', 'r') 时,Python 会以纯文本形式读取文档并尝试使用一些依赖于语言环境的默认值对其进行解码,在您的情况下显然是 GBK。 lxml 对于二进制流应该没问题,所以你应该尝试用 open('page.html', 'rb') 打开它。或者您使用encoding= 参数指定正确的编码。注意:根据页面的保存方式,文档中的编码声明可能正确也可能不正确。 @lenz,它说“TypeError: 'from_encoding' is an invalid keyword argument for open()” 参数叫encoding,不是from_encoding @lenz,它说“ValueError:二进制模式不接受编码参数”。 【参考方案1】:

一切正常,直到最近它改为 Python 3。

默认情况下,Python 3 具有以 unicode 编码的字符串,因此当您以文本形式打开文件时,它会尝试对其进行解码。 另一方面,Python 2 使用字节串,而是按原样返回文件的内容。 尝试将 page.html 作为字节对象 (open('page.html', 'rb')) 打开,看看是否适合您。

【讨论】:

感谢您的回复。它又给出了 1 个警告,说: UserWarning:没有明确指定解析器,所以我正在使用适用于该系统的最佳 HTML 解析器(“lxml”)。这通常不是问题,但如果您在另一个系统或不同的虚拟环境中运行此代码,它可能会使用不同的解析器并表现不同。 这是来自 BeautifulSoup 的警告,请参阅此处了解如何摆脱它:***.com/questions/33511544/… 这是一条额外的警告信息。问题依然存在。 @MarkK 你是说你以二进制模式(open(..., 'rb'))打开了文档,你仍然得到一个UnicodeDecodeError @GPhilo,看来问题不在 BeautifulSoup 部分。我发布了一些更改,这有助于解决问题。【参考方案2】:

我完成了 2 项更改,但不确定哪一项(或两者)生效。

计算机已格式化并重新安装,因此某些设置有所不同。

1.在语言设置中,

Administrative language settings > Change system locale > 

打勾

Beta: Use Unicode UTF-8 for worldwide language support

2.关于编码,例如,这是原行:

print (soup.find_all('span', attrs='class': 'listing-row__price')[0].text.strip().encode("utf-8"))

当 ".encode("utf-8")" 部分被删除后,它就起作用了。

2019 年 10 月 16 日更新 上面的变更工作,但勾选框时。外文软件中的字体和文字无法正常显示。

Beta: Use Unicode UTF-8 for worldwide language support

取消勾选后,外文软件中的字体和文字显示良好。但是,问题中的问题仍然存在。

未勾选的解决方案 - 外语软件和 Python 代码都可以:

soup = BeautifulSoup(open(pages, 'r', encoding = 'utf-8', errors='ignore'), "lxml")

【讨论】:

第二个是“解决”您的问题,通过简单地打印原始字节字符串而不是尝试将其编码为 UTF-8。您的文本中仍有无效的 unicode 字符,但如果这对您的使用不重要,则忽略它们是一个不错的选择;) @GPhilo,但它似乎不是 - 当框“测试:使用 Unicode UTF-8 全球语言支持”取消勾选时,问题再次出现。 (当部分“.encode("utf-8")”被删除时,它不起作用。)

以上是关于Python 3 时来自 BeautifulSoup 的“非法多字节序列”错误的主要内容,如果未能解决你的问题,请参考以下文章

Python 3 时来自 BeautifulSoup 的“非法多字节序列”错误

python 抓取图片

每当有来自串行端口 python 3.x 的新数据时,从串行数据更新 tkinter 标签

如何使用python从网站中提取所有链接[重复]

python网络爬虫 - 如何伪装逃过反爬虫程序

beautifulsoup模块