BeautifulSoup tag.children получает только нечетные элементы - PullRequest
0 голосов
/ 20 ноября 2018

Я хочу переместить элементы из одного тега в другой тег, используя следующий код:

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 голосов
/ 20 ноября 2018

Похоже, что элементы, перемещаемые из «супа» в «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)

Созданиекопия списка решает проблему.

output

<div><p>I wish I was bold.</p><p>me too</p><p>me three</p><p>me 4</p><p>5</p></div>
0 голосов
/ 20 ноября 2018

Когда вы добавляете к тегу d в первом случае, вы фактически изменяете размер soup.body.children, поскольку он перемещает теги с soup на d.

Таким образом он захватывает тег в 0 и перемещает его в d.Когда он возвращается к тегу в 1, все они сдвигаются, и он первоначально захватывает тег в индексе 2.

Один из способов увидеть это в действии - фактически печатать list(soup.body.children) в каждой итерации.Примерно так:

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

Вывод:

0 #<-- It's accessing this element
[<p>me too</p>, <p>me three</p>, <p>me 4</p>, <p>5</p>]

1
[<p>me too</p>, <p>me 4</p>, <p>5</p>]

2
[<p>me too</p>, <p>me 4</p>]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...