Python3,BeautifulSoup删除段落标记

时间:2014-08-11 19:19:00

标签: python html python-3.x beautifulsoup html-parsing

如果有以下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)

1 个答案:

答案 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环境中安装了lxmlBeautifulSoup将其用作底层解析器,因为您尚未明确指定它。