You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用BeautifulSoup复制标签并插入到被复制标签之后?

问题描述

存在大量class名相同的标签,这类标签结构较长且嵌套了其他标签,简化测试代码如下:

from bs4 import BeautifulSoup

HTML = '''
<p class=test>111</p>
<p class=test>222</p>
<p class=test>333</p>
<p class=test>444</p>
<p class=test>555</p>
'''
soup = BeautifulSoup(HTML, 'lxml')

origin_tag = soup.select('p.test')
print(len(origin_tag)) # 运行结果为5
origin_tag.insert(1, origin_tag[1])
print(len(origin_tag)) # 运行结果为6
print(soup)  # 实际HTML内容无任何变化,未达到预期

预期运行后输出的HTML结构为:

<p class=test>111</p>
<p class=test>222</p>
<p class=test>222</p>
<p class=test>333</p>
<p class=test>444</p>
<p class=test>555</p>

实际运行时,soup.select('p.test')可正常获取到5个p标签,对返回的列表执行insert操作插入原索引1位置的标签后,列表长度显示为6,但打印soup时HTML内容没有任何变化,无法得到预期结果,需要实现标签的复制与插入操作。

问题原因
  • soup.select()返回的是Python原生列表,仅保存了匹配到的标签对象引用,直接对这个列表做增删改操作只会修改列表本身,不会改动BeautifulSoup维护的DOM树结构。
  • 就算直接操作DOM插入已存在的标签对象,也只是移动标签的原有位置,不会生成新的重复标签。
解决方法

需要先对要复制的标签做深拷贝,再调用标签自带的DOM操作方法插入新节点,不要直接修改select返回的列表,参考代码如下:

from bs4 import BeautifulSoup
import copy

HTML = '''
<p class=test>111</p>
<p class=test>222</p>
<p class=test>333</p>
<p class=test>444</p>
<p class=test>555</p>
'''
soup = BeautifulSoup(HTML, 'lxml')

origin_tags = soup.select('p.test')
# 深拷贝目标标签,嵌套标签也会被完整复制,不影响原节点
copied_tag = copy.deepcopy(origin_tags[1])
# 在原索引1的标签后方插入复制出的新标签
origin_tags[1].insert_after(copied_tag)

print(soup)

运行上述代码即可得到预期的HTML输出。

注意:如果标签存在多层嵌套,必须使用copy.deepcopy()做深拷贝,浅拷贝会导致内部子节点仍关联原DOM,引发结构异常。

内容的提问来源于stack exchange,提问作者simon chang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:15:27