我现在对一些我认为我理解的事情感到困惑,但事实证明我一直认为这是理所当然的。
人们经常遇到这种类型的for
循环:
from bs4 import BeautifulSoup as bs
mystring = 'some string'
soup = bs(mystring,'html.parser')
for elem in soup.find_all():
[do something with elem]
elem
在我遇到这个简化字符串的一个版本之前,我没有过多关注的是实际情况:
mystring = 'opening text<p>text one<BR> text two.<br></p>\
<p align="right">text three<br/> text four.</p><p class="myclass">text five. </p>\
<p>text six <span style="some style">text seven</span></p>\
<p>text 8. <span style="some other style">text nine</span></p>closing text'
我不再确定我期望的输出是什么,但是当我运行这段代码时:
counter = 1 #using 'normal' counting for simplification
for elem in soup.find_all():
print('elem ',counter,elem)
counter +=1
输出是:
elem 1 <p>text one<br/> text two.<br/></p>
elem 2 <br/>
elem 3 <br/>
elem 4 <p align="right">text three<br> text four.</br></p>
elem 5 <br> text four.</br>
elem 6 <p class="myclass">text five. </p>
elem 7 <p>text six <span style="some style">text seven</span></p>
elem 8 <span style="some style">text seven</span>
elem 9 <p>text 8. <span style="some other style">text nine</span></p>
elem 10 <span style="some other style">text nine</span>
所以 bs4+html.parser 在字符串中找到了 10 个元素。他们的选择和呈现对我来说似乎不直观(例如,跳过opening text
和closing text
)。不仅如此,print(len(soup))
结果是7
!
所以为了确保,我换掉html.parser
了lxml
和html5lib
. 在这两种情况下,print(len(soup))
不仅是1
,而且elem
s 的数量也跃升至 13!而且,自然地,额外的元素是不同的。从第 4 次elem
到最后,两个库都与html.parser
. 然而,对于前三个...
与html5lib
您一起获得:
elem 1 <html><head></head><body>opening text<p>text one<br/> text two.<br/></p><p align="right">text three<br/> text four.</p><p class="myclass">text five. </p><p>text six <span style="some style">text seven</span></p><p>text 8. <span style="some other style">text nine</span></p>closing text</body></html>
elem 2 <head></head>
elem 3 <body>opening text<p>text one<br/> text two.<br/></p><p align="right">text three<br/> text four.</p><p class="myclass">text five. </p><p>text six <span style="some style">text seven</span></p><p>text 8. <span style="some other style">text nine</span></p>closing text</body>
lxml
另一方面,使用,您会得到:
elem 1 <html><body><p>opening text</p><p>text one<br/> text two.<br/></p><p align="right">text three<br/> text four.</p><p class="myclass">text five. </p><p>text six <span style="some style">text seven</span></p><p>text 8. <span style="some other style">text nine</span></p>closing text</body></html>
elem 2 <body><p>opening text</p><p>text one<br/> text two.<br/></p><p align="right">text three<br/> text four.</p><p class="myclass">text five. </p><p>text six <span style="some style">text seven</span></p><p>text 8. <span style="some other style">text nine</span></p>closing text</body>
elem 3 <p>opening text</p>
那么这一切背后的哲学是什么?是谁的“错”?有“正确”或“错误”的答案吗?而且,实际上,我应该只虔诚地遵循一个解析器,还是每个解析器都有时间和地点?
为问题的长度道歉。