BeautifulSoup tag.children仅获得奇数元素

时间:2018-11-20 19:28:50

标签: python beautifulsoup

我想使用以下代码将元素从一个标签移动到另一个标签:

soup = BeautifulSoup("<p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p>")
d = soup.new_tag('div')
for tag in soup.body.children:
    d.append(tag)

但是,这会产生...

>>> d
<div><p>I wish I was bold.</p><p>me three</p><p>5</p></div>

仅奇数元素被移动。我检查了soup.body.children,以查看其外观(在移动任何东西之前),所有标签似乎都在那里:

>>> list(soup.body.children)
[<p>I wish I was bold.</p>, <p>me too</p>, <p>me three</p>, <p>me 4</p>, <p>5</p>]

当我遍历list(soup.body.children)时,一切都会按预期进行:

soup = BeautifulSoup("<p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p>")
d = soup.new_tag('div')
for tag in list(soup.body.children):
    d.append(tag)
>>> d
<div><p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p></div>

为什么在soup.body.children上进行迭代只能访问奇数标记,而在list(soup.body.children)上进行迭代却可以访问所有标记?

2 个答案:

答案 0 :(得分:1)

在第一种情况下,当您附加到d标签时,实际上是在更改soup.body.children的大小,因为它会从{{ 1}}到soup

因此,它在0处捕获了标签并将其移至d。当它返回标记1时,它们都移了过来,它最初在索引2处捕获了标记。

一种实际使用的方法是在每次迭代中实际打印d。像这样:

list(soup.body.children)

输出:

for i, tag in enumerate(soup.body.children):
    d.append(tag)
    print(i)
    print(list(soup.body.children))
    print()

答案 1 :(得分:0)

似乎将从“汤”移到“ d”的项目会影响迭代器,即在您遍历项目时将其删除并更改“汤”生成器。

soup = BeautifulSoup("<p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p>")
d = soup.new_tag('div')
children = list(soup.body.children).copy()
for tag in children:
    d.append(tag)


print(d)

创建列表的副本即可解决问题。

输出

<div><p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p></div>