如果有以下html块:
chunk = '<p>BLA bla bla html... <div>Copyright 2014 NPR</div></p>'
当我执行以下操作时:
from bs4 import BeautifulSoup
soup = BeautifulSoup(chunk)
大块变成了这个:
>>> soup
<html><body><p>BLA bla bla html... </p><div>Copyright 2014 Someone</div></body></html>
段落标记提前关闭,div被拉出来。
我对此感到惊讶。这是BeautifulSoup的预期行为,如果是这样,任何人都能解释为什么会这样做吗?
编辑:请注意,我意识到这个HTML无效,但我没有意识到BeautifulSoup会将无效的html编辑到这个程度。 Here's a related SO question on invalid HTML (div instead a p tag)
答案 0 :(得分:3)
您提供的HTML不是一个有效的格式良好的HTML。在这种情况下,如documentation:
中所述HTML解析器之间也存在差异。如果你给美丽 汤是一个完美形成的HTML文档,这些差异无关紧要。 一个解析器会比另一个解析器更快,但他们都会给你一个 数据结构看起来与原始HTML文档完全相同。
但是如果文档没有完美形成,不同的解析器会 给出不同的结果。
因此,BeautifulSoup
使用的行为depends on the underlying parser。而且,由于您尚未明确指定,BeautifulSoup
会选择according to the ranking:
如果您没有指定任何内容,您将获得最佳的HTML解析器 安装。然后,Beautiful Soup将lxml的解析器列为最佳解析器 html5lib,然后是Python的内置解析器。
这是不同解析器尝试使用您提供的html进行的操作:
>>> from bs4 import BeautifulSoup
>>> chunk = '<p>BLA bla bla html... <div>Copyright 2014 NPR</div></p>'
# html.parser
>>> BeautifulSoup(chunk, 'html.parser')
<p>BLA bla bla html... <div>Copyright 2014 NPR</div></p>
# html5lib
>>> BeautifulSoup(chunk, 'html5lib')
<html><head></head><body><p>BLA bla bla html... </p><div>Copyright 2014 NPR</div><p></p></body></html>
# lxml
>>> BeautifulSoup(chunk, 'lxml')
<html><body><p>BLA bla bla html... </p><div>Copyright 2014 NPR</div></body></html>
# xml
>>> BeautifulSoup(chunk, 'xml')
<?xml version="1.0" encoding="utf-8"?>
<p>BLA bla bla html... <div>Copyright 2014 NPR</div></p>
根据输出,您在此特定python环境中安装了lxml
,BeautifulSoup
将其用作底层解析器,因为您尚未明确指定它。