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

如何在BeautifulSoup对象中移除无信息冗余HTML <div>标签?

清理BeautifulSoup中的冗余<div>标签

刚好做过类似的HTML清理需求,这种纯粹用来嵌套、既不带任何属性也不含实际内容的<div>确实烦人,尤其是某些自动生成的HTML会搞出一堆没用的层级。从树结构的角度来说,我们要做的就是合并那些仅作为“空容器”的嵌套div节点——把它们的子节点直接提升到父节点的位置,同时移除完全空的div。

实现思路

核心逻辑是遍历DOM树,从最底层的节点开始向上处理:

  • 找到满足以下条件的<div>:无任何属性(class/style/id等)、唯一子节点也是<div>、自身无有效文本内容
  • 将这类节点替换成它的子节点,实现层级扁平化
  • 最后移除那些完全空的、没有任何内容或子节点的<div>

代码实现

from bs4 import BeautifulSoup

# 原始HTML
html = """
<html> <body> <div> <div> <div> <div> <div> <div> Close </div> </div> </div> </div> </div> <div> <div> <div style="width:80px"> <div> </div> <div> <button> Close </button> </div> </div> </div> </div> </div> <div> </div> </body> </html>
"""

# 解析HTML
soup = BeautifulSoup(html, 'html.parser')

def remove_redundant_divs(node):
    # 先递归处理所有子节点,从下往上清理,避免遗漏深层嵌套
    for child in list(node.children):
        if child.name == 'div':
            remove_redundant_divs(child)
    
    # 判断当前节点是否为冗余div
    if (node.name == 'div' 
        and not node.attrs  # 无任何属性
        and len(list(node.children)) == 1  # 仅有一个子节点
        and list(node.children)[0].name == 'div'):  # 子节点也是div
        # 用子节点替换当前节点,实现层级提升
        node.replace_with(list(node.children)[0])

# 开始清理冗余div
remove_redundant_divs(soup.body)

# 移除完全空的div(没有文本、没有子节点)
for empty_div in soup.find_all('div', string=lambda s: s is None or s.strip() == '', recursive=True):
    if not list(empty_div.children):
        empty_div.decompose()

# 输出清理后的HTML
print(soup.prettify())

效果验证

运行后会得到你想要的结构:

<html>
 <body>
  <div>
   Close
  </div>
  <div style="width:80px">
   <button>
    Close
   </button>
  </div>
 </body>
</html>

注意事项

  • 递归处理顺序是从下往上,这样深层嵌套的冗余div会先被清理,上层的div可能会因为子节点被替换后变成冗余节点,进而被处理
  • 只有完全符合“无属性+仅一个div子节点”的div才会被替换,带属性的div(比如示例里的style="width:80px")会被保留
  • 额外的空div清理步骤可以移除那些完全没有内容的“空容器”,让HTML更干净

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:59:31