BeautifulSoup无法解析嵌套的<p>元素</p>

时间:2014-04-28 14:14:17

标签: python beautifulsoup

依赖关系: BeautifulSoup == 3.2.1

In: from BeautifulSoup import BeautifulSoup
In: BeautifulSoup('<p><p>123</p></p>')
Out: <p></p><p>123</p>

为什么两个相邻的标签不在输出中?

3 个答案:

答案 0 :(得分:4)

这只是BS3的解析器修复你的broken html

  

P元素代表一个段落。它不能包含块级   元素(包括P本身)。

答案 1 :(得分:2)

<p><p>123</p></p>

是无效的HTML。 p s无法嵌套。 BS试图清理它。

当BS遇到第二个<p>时,它认为第一个p已完成,因此它会插入一个结束</p>。输入中的第二个</p>与开头<p>不匹配,因此会被删除。

答案 2 :(得分:2)

这是因为BeautifulSoup具有此NESTABLE_TAGS概念/设置:

  

当Beautiful Soup正在解析文档时,它会保持一堆打开   标签。每当它看到一个新的开始标记时,它就会抛出该标记   堆栈。但在此之前,它可能会关闭一些开放标签   并从堆栈中删除它们。它关闭的标签取决于   它刚刚找到的标签的质量,以及标签的质量   叠加。

     

因此,当Beautiful Soup遇到<P>标签时,它会关闭并弹出所有标签   标签最多包括以前遇到的标签   相同的类型。这是默认行为,这就是方法   BeautifulStoneSoup处理每个标签。这是标签的结果   在NESTABLE_TAGS或RESET_NESTING_TAGS中没有提到。这也是   当标签出现在RESET_NESTING_TAGS但没有时,你得到了什么   在NESTABLE_TAGS中输入<P>标记的方式。

>>> pprint(BeautifulSoup.NESTABLE_TAGS)
{'bdo': [],
 'blockquote': [],
 'center': [],
 'dd': ['dl'],
 'del': [],
 'div': [],
 'dl': [],
 'dt': ['dl'],
 'fieldset': [],
 'font': [],
 'ins': [],
 'li': ['ul', 'ol'],
 'object': [],
 'ol': [],
 'q': [],
 'span': [],
 'sub': [],
 'sup': [],
 'table': [],
 'tbody': ['table'],
 'td': ['tr'],
 'tfoot': ['table'],
 'th': ['tr'],
 'thead': ['table'],
 'tr': ['table', 'tbody', 'tfoot', 'thead'],
 'ul': []}

作为解决方法,您可以允许p代码位于p内:

>>> from BeautifulSoup import BeautifulSoup
>>> BeautifulSoup.NESTABLE_TAGS['p'] = ['p']
>>> BeautifulSoup('<p><p>123</p></p>')
<p><p>123</p></p>

此外,不再维护BeautifulSoup第3版 - 您应该切换到BeautifulSoup4

使用BeautifulSoup4时,您可以更改基础parser以更改行为:

>>> from bs4 import BeautifulSoup
>>> BeautifulSoup('<p><p>123</p></p>')
<html><body><p></p><p>123</p></body></html>
>>> BeautifulSoup('<p><p>123</p></p>', 'html.parser')
<p><p>123</p></p>
>>> BeautifulSoup('<p><p>123</p></p>', 'xml')
<?xml version="1.0" encoding="utf-8"?>
<p><p>123</p></p>
>>> BeautifulSoup('<p><p>123</p></p>', 'html5lib')
<html><head></head><body><p></p><p>123</p><p></p></body></html>