如何用Python清理劣质HTML中的孤立文本并统一用<div>包裹?
通用HTML清理算法:将所有内容包裹进
标签
核心思路
遍历HTML结构,把所有**未被块级容器(如
、
等)包裹的连续内容(包括孤立文本、///等内联元素)**统一包裹进
标签,同时完整保留原有内联格式和媒体元素。
实现步骤(基于BeautifulSoup)
1. 定义标签范围
先明确需要跳过的块级容器标签,以及需要被打包的内联元素:
from bs4 import BeautifulSoup, NavigableString, Tag # 常见块级标签,本身已是容器无需重新包裹 BLOCK_TAGS = {'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'table', 'tr', 'td'} # 内联标签和文本节点需被包裹进<div> INLINE_TAGS = {'b', 'strong', 'i', 'em', 'a', 'img', 'span', 'br'}
2. 递归处理节点函数
编写递归函数,遍历节点子元素,将连续内联内容打包成
:
def wrap_inline_content(node): current_group = [] # 遍历子节点副本,避免修改原列表导致索引异常 for child in list(node.children): if isinstance(child, NavigableString): # 跳过纯空白文本 if child.strip(): current_group.append(child) elif isinstance(child, Tag): if child.name in BLOCK_TAGS: # 先处理已收集的内联组 if current_group: wrap_div = soup.new_tag('div') for item in current_group: wrap_div.append(item) child.insert_before(wrap_div) current_group = [] # 递归处理块级标签内部内容 wrap_inline_content(child) elif child.name in INLINE_TAGS: current_group.append(child) else: # 未知标签视为内联元素处理 current_group.append(child) # 处理最后一组剩余的内联内容 if current_group: wrap_div = soup.new_tag('div') for item in current_group: wrap_div.append(item) node.append(wrap_div)
3. 执行清理流程
# 示例劣质HTML代码 dirty_html = """ 这是一段孤立的文本,没有被<div>包裹 <b>加粗文本</b>和<i>斜体文本</i>也在外面 <div>已经被包裹的内容</div> <img src="test.jpg" alt="测试图片">这是图片后的孤立文本 """ # 解析并处理HTML soup = BeautifulSoup(dirty_html, 'html.parser') wrap_inline_content(soup) # 输出清理后的代码 print(soup.prettify())
效果说明
- 所有孤立文本、零散内联标签都会被自动包裹进
- 原有块级标签内部的内容会被递归处理,确保嵌套内容符合要求
- 完全保留原有格式、图片链接等信息
内容的提问来源于stack exchange,提问作者Code Monkey
相关产品推荐
相关产品推荐

