我有一段像这样的HTML:
<figure>
<img src=".." alt=".." />
Some text that I have to wrap in <code>figcaption</code>
</figure>
我正在尝试将<img>
后面的所有内容包装在<figcaption>
中。这可能吗?
next_elements
可以很好地获取我想要的元素,但返回一个生成器,它与wrap
方法不能很好地配合。
答案 0 :(得分:2)
这是一种方法:
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup("""
... <figure>
... <img src=".." alt=".." />
... Some text that I have to wrap in <code>figcaption</code>
... </figure>
... """)
>>> for figure in soup.find_all("figure"):
... img = figure.find("img")
... if img is not None:
... figcaption = soup.new_tag("figcaption")
... for el in list(img.next_siblings):
... figcaption.append(el)
... img.insert_after(figcaption)
...
>>> soup
<html><body><figure>
<img alt=".." src=".."/><figcaption>
Some text that I have to wrap in <code>figcaption</code>
</figcaption></figure></body></html>
有几点需要注意:
我们使用next_siblings
,它只返回我们实际需要的元素,而不是next_elements
,它将继续超过figure
元素的末尾。
我们用next_siblings
打包list()
以创建一个我们可以迭代的浅副本 - 否则,因为将el
附加到figcaption
的行为会将其从它在文档树中的前一个位置,它将修改我们要迭代的序列,即a bad idea。我们本来可以使用find_next_siblings()
(也会返回一个列表),但上面的版本更明确。
由于我们已经从文档树中以前的位置删除了img
的所有下一个兄弟,我们需要做的就是附加figcaption
(img
元素后面的(现在包含它们)。
空白的位置对于人类来说不再是直觉“正确”,但修复它需要大量的额外工作,而且可能不值得。