我注意到Python [3.6.5] BeautifulSoup [4.6.0]和“lxml”[4.2.1]解析器如何处理长bytes
个对象与长字符串之间存在奇怪的不一致。 (显然,“long”是> 16,384 = 2 ** 14个字符或字节。)
例如,我从麻省理工学院网站下载奥赛罗的文本,并以原始(字节)形式和解码为字符串后将其提供给BS。两个对象具有相同的长度,因为文档中没有多字节字符。
from bs4 import BeautifulSoup
import urllib
url = "http://shakespeare.mit.edu/othello/full.html"
html_raw = urllib.request.urlopen(url).read()
html_str = urllib.request.urlopen(url).read().decode("iso-8859-1")
type(html_raw), len(html_raw)
#(<class 'bytes'>, 304769)
type(html_str), len(html_str)
#(<class 'str'>, 304769)
对于较短的字符串/字节,结果汤是相同的,但对于较长的字符串/字节则不同。也就是说,用字符串生成的汤突然开始将单词作为单独的字符处理,而从字节生成的汤正确处理整个文件:
BeautifulSoup(html_raw[:16410], "lxml")
#... <i>Enter OTHELLO, IAGO, and Attendants with torches</i>
#</blockquote>
#<a></a></body></html>
BeautifulSoup(html_str[:16410], "lxml")
#... <i>Enter OTHELLO, IAGO, and Attendants with torch e s / i >
# / b l o c k q u o t e >
#
# A </i></blockquote></body></html>
这既适用于文档的子集(上图),也适用于整个文档:
BeautifulSoup(html_raw, "lxml")
#...
#<p><i>Exeunt</i></p>
#</blockquote></body>
#</html>
BeautifulSoup(html_str, "lxml")
#...
# p > i > E x e u n t / i > / p >
# / h t m l >
#
#
# </i></blockquote></body></html>
使用“html.parser”时输出之间没有区别。
这是BS实施中的错误吗?或者我是否违反了一些无证(或记录?)的假设?
答案 0 :(得分:0)
不是因为文件大小,问题可能仅在Linux中发生,因为在Windows中它可以正常工作。这是因为html的字符集为windows-1252
,所以添加.encode()
就可以解决问题
soup_raw = BeautifulSoup(html_raw, "lxml").encode("iso-8859-1")
soup_str = BeautifulSoup(html_str.encode("iso-8859-1"), "lxml")