如何用BeautifulSoup将父级含<li>的子<li>标签替换为<SOME>
解决嵌套标签替换为标签的问题
需求说明
需要将所有父级包含
给定HTML代码
<html> <body> Free Text: Above <ul> <li> data 1 </li> <li> <ul> <li> <ol start = "321"> <li> sub-sub list 1 <ol> <li> sub sub sub list </li> </ol> </li> <li> sub-sub list 2 </li> </ol> </li> <li> sub list 2 </li> <li> sub list 3 </li> </ul> </li> <li> <p> list type paragraph </p> data 3 </li> </ul> Free Text: Middle <ul> <li> Second UL list </li> <li> Second List part 2 </li> </ul> Free Text : Below </body> </html>
期望转换结果
<html> <body> Free Text: Above <ul> <li> data 1 </li> <li> <ul> <SOME> <ol start = "321"> <SOME> sub-sub list 1 <ol> <SOME> sub sub sub list </SOME> </ol> </SOME> <SOME> sub-sub list 2 </SOME> </ol> </SOME> <SOME> sub list 2 </SOME> <SOME> sub list 3 </SOME> </ul> </li> <li> <p> list type paragraph </p>data 3 </li> </ul> Free Text: Middle <ul> <li> Second UL list </li> <li> Second List part 2 </li> </ul> Free Text : Below </body> </html>
原代码问题分析
原代码存在两个核心问题:
- 替换时仅用
new_tag.string = tag.text复制纯文本,丢失了 - 内部的所有子标签(如嵌套的
- ),不符合结构保留的要求。
- 复制内容的方式错误,导致深层嵌套的
- 替换后结构完全丢失。
修正后的解决方案
from bs4 import BeautifulSoup given = """<html> <body> Free Text: Above <ul> <li> data 1 </li> <li> <ul> <li> <ol start = "321"> <li> sub-sub list 1 <ol> <li> sub sub sub list </li> </ol> </li> <li> sub-sub list 2 </li> </ol> </li> <li> sub list 2 </li> <li> sub list 3 </li> </ul> </li> <li> <p> list type paragraph </p> data 3 </li> </ul> Free Text: Middle <ul> <li> Second UL list </li> <li> Second List part 2 </li> </ul> Free Text : Below </body> </html>""" soup = BeautifulSoup(given, 'html.parser') # 遍历所有<li>标签,深度优先确保先处理内层节点 for tag in soup.find_all('li'): # 判断当前<li>是否存在<li>类型的祖先节点 if tag.find_parent('li'): new_tag = soup.new_tag("SOME") # 将原<li>的所有子节点(文本+标签)迁移到新标签中 for child in tag.contents: new_tag.append(child) # 替换原<li>标签 tag.replace_with(new_tag) result = str(soup) print(result)
代码说明
- 遍历顺序:
soup.find_all('li')默认按深度优先遍历,会先处理最内层的 - ,避免外层节点替换后影响内层节点的查找。
- 条件判断:使用
tag.find_parent('li')高效判断当前 - 是否嵌套在其他
- 内部,只要存在符合条件的祖先就执行替换。
- 节点迁移:通过遍历
tag.contents将原 - 的所有子节点(包括文本和嵌套标签)逐个添加到新的
标签中,完整保留原有结构。
内容的提问来源于stack exchange,提问作者Deshwal
相关产品推荐
相关产品推荐

