【问题标题】:beautifulsoup next_siblings generator doesn't loopbeautifulsoup next_siblings 生成器不循环
【发布时间】:2020-08-31 06:56:24
【问题描述】:

这是该问题的示例复制

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', exists)
tables = soup('<div></div>', '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 错误还是一个漂亮的汤错误,或者这是预期的行为?

λ pip freeze | grep 'beautifulsoup4'
beautifulsoup4==4.9.1

λ python -V
Python 3.8.0

【问题讨论】:

  • 这并不奇怪...在第一个示例中,您正在更改文档树,同时对其进行迭代。 div.append(sib) 将从树中删除sib(在这种情况下,sib 的类型为空NavigableString)并且循环结束。正如您所写,您需要首先将兄弟姐妹放入一个列表,然后对其进行迭代。
  • 我不知道附加到不同的树会从现有的树中删除它。我只是看了一下来源,假设它会复制。谢谢你。 @AndrejKesely 你想回答这个问题吗?

标签: python beautifulsoup generator


【解决方案1】:

在你的第一个例子中:

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) 从文档树exists 中删除sib 并将其放置在树tables 中。这是不好的做法,因为它只进行一次迭代。

在第一次迭代中,sib 的类型为 NavigableString,值为 "\n"(换行符)。所以当你打印tables时,你可以在&lt;div&gt;标签后面看到一个换行符。

正确的做法是将兄弟姐妹存储到列表中,然后遍历该列表。

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 2015-05-12
    • 2015-04-01
    • 1970-01-01
    • 2017-10-05
    • 2019-07-07
    • 2012-07-17
    • 2014-01-21
    相关资源
    最近更新 更多