首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用BeautifulSoup包装标签的内容

用BeautifulSoup包装标签的内容
EN

Stack Overflow用户
提问于 2014-03-25 10:53:16
回答 2查看 3K关注 0票数 0

我想用BeautifulSoup包装标签的内容。这是:

代码语言:javascript
复制
<div class="footnotes">
    <p>Footnote 1</p>
    <p>Footnote 2</p>
</div>

应该变成这样:

代码语言:javascript
复制
<div class="footnotes">
  <ol>
    <p>Footnote 1</p>
    <p>Footnote 2</p>
  </ol>
</div>

因此,我使用以下代码:

代码语言:javascript
复制
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]

但我得到了以下信息:

代码语言:javascript
复制
<div class="footnotes"><ol><
    ></
    ><<p>Footnote 1</p>></<p>Footnote 1</p>><
    ></
    ><<p>Footnote 2</p>></<p>Footnote 2</p>><
></
></ol></div>

有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-25 12:00:03

使用lxml:

代码语言:javascript
复制
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()))

版画

代码语言:javascript
复制
<html><body><div class="footnotes">
    <ol><p>Footnote 1</p>
    <p>Footnote 2</p>
</ol></div></body></html>

请注意,使用lxml,元素(标记)只能位于树中的一个位置(因为每个元素只有一个父元素),因此在ol中追加tag也会从footnote中删除它。因此,与BeautifulSoup不同,您不需要按反向顺序遍历内容,也不需要使用insert(0,...)。你只是按顺序追加。

使用BeautifulSoup:

代码语言:javascript
复制
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)

版画

代码语言:javascript
复制
<html><body><div class="footnotes"><ol>
<p>Footnote 1</p>
<p>Footnote 2</p>
</ol></div></body></html>
票数 4
EN

Stack Overflow用户

发布于 2014-03-25 11:28:36

只需使用.contents移动标记的tag.extract();不要尝试用soup.new_tag重新创建它们(soup.new_tag只使用标记名,而不是整个标记对象)。不要在原始标记上调用.clear().extract()已经删除了元素。

当内容被就地修改时,将项目反向移动,如果不小心,则会导致跳过的元素。

最后,当您只需要对一个标记执行此操作时,请使用.find()

您确实需要创建contents列表的副本,因为它将被修改到位

代码语言:javascript
复制
footnotes = soup.find("div", { "class" : "footnotes" })
new_ol = soup.new_tag("ol")

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

footnotes.append(new_ol)

演示:

代码语言:javascript
复制
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('''\
... <div class="footnotes">
...     <p>Footnote 1</p>
...     <p>Footnote 2</p>
... </div>
... ''')
>>> footnotes = soup.find("div", { "class" : "footnotes" })
>>> new_ol = soup.new_tag("ol")
>>> for content in reversed(footnotes.contents):
...     new_ol.insert(0, content.extract())
... 
>>> footnotes.append(new_ol)
>>> print footnotes
<div class="footnotes"><ol>
<p>Footnote 1</p>
<p>Footnote 2</p>
</ol></div>
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22632355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档