用 BeautifulSoup 包装标签的内容

slw*_*lwr 1 python lxml beautifulsoup

我试图用 BeautifulSoup 包装标签的内容。这:

<div class="footnotes">
    <p>Footnote 1</p>
    <p>Footnote 2</p>
</div>
Run Code Online (Sandbox Code Playgroud)

应该变成这样:

<div class="footnotes">
  <ol>
    <p>Footnote 1</p>
    <p>Footnote 2</p>
  </ol>
</div>
Run Code Online (Sandbox Code Playgroud)

所以我使用以下代码:

footnotes = soup.findAll("div", { "class" : "footnotes" })
footnotes_contents = ''
new_ol = soup.new_tag("ol") 
for content in footnotes[0].children:
    new_tag = soup.new_tag(content)
    new_ol.append(new_tag)

footnotes[0].clear()
footnotes[0].append(new_ol)

print footnotes[0]
Run Code Online (Sandbox Code Playgroud)

但我得到以下信息:

<div class="footnotes"><ol><
    ></
    ><<p>Footnote 1</p>></<p>Footnote 1</p>><
    ></
    ><<p>Footnote 2</p>></<p>Footnote 2</p>><
></
></ol></div>
Run Code Online (Sandbox Code Playgroud)

建议?

unu*_*tbu 5

使用lxml:

import lxml.html as LH
import lxml.builder as builder
E = builder.E

doc = LH.parse('data')
footnote = doc.find('//div[@class="footnotes"]')
ol = E.ol()
for tag in footnote:
    ol.append(tag)
footnote.append(ol)
print(LH.tostring(doc.getroot()))
Run Code Online (Sandbox Code Playgroud)

印刷

<html><body><div class="footnotes">
    <ol><p>Footnote 1</p>
    <p>Footnote 2</p>
</ol></div></body></html>
Run Code Online (Sandbox Code Playgroud)

请注意,使用 时lxml,元素(标签)只能位于树中的一个位置(因为每个元素只有一个父元素),因此追加到tag也会ol将其从 中删除footnote。因此,与 BeautifulSoup 不同,您不需要以相反的顺序迭代内容,也不需要使用insert(0,...). 您只需按顺序附加即可。


使用美丽汤:

import bs4 as bs
with open('data', 'r') as f:
    soup = bs.BeautifulSoup(f)

footnote = soup.find("div", { "class" : "footnotes" })
new_ol = soup.new_tag("ol")

for content in reversed(footnote.contents):
    new_ol.insert(0, content.extract())

footnote.append(new_ol)
print(soup)
Run Code Online (Sandbox Code Playgroud)

印刷

<html><body><div class="footnotes"><ol>
<p>Footnote 1</p>
<p>Footnote 2</p>
</ol></div></body></html>
Run Code Online (Sandbox Code Playgroud)