如何解决beautifulsoup next_siblings生成器未循环
此问题的样本复制品
from bs4 import BeautifulSoup as soup
data = soup("""
<div>
<h3 id="pivot"></h3>
<table></table>
<h3 id="next-head"></h3>
<table></table>
<h3 id="next2-head"></h3>
</div>
""",'lxml')
exists = data.find('h3',{'id': 'pivot'})
print('exists',exists)
tables = soup('<div></div>','lxml')
div = tables.find('div')
for sib in (exists.next_siblings):
print('sibling',sib)
if sib.name == 'h3':
print('break')
break
div.append(sib)
print('tables',tables)
上面的代码什么都不打印
输出:
exists <h3 id="pivot"></h3>
sibling
tables <html><body><div>
</div></body></html>
而另一个变体可以正常工作
# same as above
...
print('exists','lxml')
div = tables.find('div')
tabs = []
for sib in (exists.next_siblings):
print('sibling',sib)
if sib.name == 'h3':
print('break')
break
tabs.append(sib)
print('tabs',tabs)
tabs变量包含预期结果,并且生成器扩展
exists <h3 id="pivot"></h3>
sibling
sibling <table></table>
sibling
sibling <h3 id="next-head"></h3>
break
tabs ['\n',<table></table>,'\n']
在第一个示例中也将生成器作为列表list(existing.next_siblings)
将解决此奇怪的问题。
这是python bug还是漂亮的汤虫bug,或者这是预期的行为?
λ pip freeze | grep 'beautifulsoup4'
beautifulsoup4==4.9.1
λ python -V
Python 3.8.0
解决方法
在您的第一个示例中:
for sib in (exists.next_siblings):
print('sibling',sib)
if sib.name == 'h3':
print('break')
break
div.append(sib)
您正在遍历文档树(使用div.append(sib)
)。命令div.append(sib)
从文档树sib
中删除exists
并将其放在树tables
中。这是 bad 的做法,因为它只会执行一次迭代。
在第一次迭代中,sib
的类型为NavigableString
,值为"\n"
(换行符)。因此,当您打印tables
时,您可以在打开<div>
标签之后看到换行符。
正确的方法是将兄弟姐妹存储在列表中,然后遍历此列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。