[英]BeautifulSoup : Weird behavior with <p>
我有以下HTML内容:
content = """
<div>
<div> <div>div A</div> </div>
<p>P A</p>
<div> <div>div B</div> </div>
<p> P B1</p>
<p> P B2</p>
<div> <div>div C</div> </div>
<p> P C1 <div>NODE</div> </p>
</div>
"""
如果我使用以下代码:
soup = bs4.BeautifulSoup(content, "lxml")
firstDiv = soup.div
allElem = firstDiv.findAll( recursive = False)
for i, el in enumerate(allElem):
print "element ", i , " : ", el
我明白了:
element 0 : <div> <div>div A</div> </div>
element 1 : <p>P A</p>
element 2 : <div> <div>div B</div> </div>
element 3 : <p> P B1</p>
element 4 : <p> P B2</p>
element 5 : <div> <div>div C</div> </div>
element 6 : <p> P C1 </p>
element 7 : <div>NODE</div>
如您所见,与元素0、2或5不同,元素6不包含其子元素。 如果我将其<p>
更改为<b>
或<div>
则它的作用与众不同。 为什么与<p>
这么小的区别? 从4.3.2升级到4.4.6时,我仍然遇到这个问题(如果这是一个问题?)。
p
元素只能包含措辞内容,因此您拥有的实际上是无效的HTML。 这是一个如何解析的示例:
例如,在措辞内容中不允许使用
form
元素,因为当解析为HTML时,form
元素的开始标记将暗示p
元素的结束标记。 因此,以下标记导致两段,而不是一段:<p>Welcome. <form><label>Name:</label> <input></form>
完全按照以下方式进行解析:
<p>Welcome. </p><form><label>Name:</label> <input></form>
您可以确认这是浏览器解析HTML的方式(图为Chrome 64):
lxml
和html5lib
正确处理此html5lib
。 html.parser
并没有实现HTML5规范的大部分内容,也不在乎这些怪癖。
如果您不希望将来因这些解析差异而感到沮丧,建议您坚持使用lxml
和html5lib
。 当您在浏览器的DOM检查器中看到的内容与代码解析方式不同时,这很烦人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.