本文详细介绍了如何使用BeautifulSoup和html2text库从复杂的HTML结构中,有效地提取并分离段落(p标签)和表格(table标签)内容。核心在于通过正确的变量作用域管理和累加器机制,将连续的段落内容合并为一项,并在遇到表格时将其作为独立项处理,从而实现对混合HTML内容的结构化提取。
在进行网页数据抓取和内容处理时,我们经常需要从HTML文档中提取特定类型的信息,并按照一定的逻辑进行分组。一个常见的场景是,我们需要将连续的文本段落(由
标签表示)合并成一个整体,而当遇到表格(由
| 表格1数据 |
这是第三段内容。
#这是第四段内容。
#| 表格2数据 |
这是第五段内容。
# # """ converter = html2text.HTML2Text() soup = BeautifulSoup(data3, 'html.parser') content_items = [] # 错误的初始化方式:在循环内部每次都创建一个新的字典 for tag in soup.descendants: content_dict = {'Title': "35.23.060 - DR Zone Standards", 'Content': ''} # 问题所在! if tag.name == "p": content_dict['Content'] += converter.handle(str(tag)) # 无法累积 elif tag.name == "table": if content_dict['Content']: # 这里的 content_dict['Content'] 几乎总是空的 content_items.append(content_dict) content_dict['Content'] = converter.handle(str(tag)) content_items.append(content_dict)上述代码的问题在于,content_dict 在每次 for 循环迭代时都会被重新创建并清空。这意味着,当处理一个
标签时,它只能捕获当前这一个
标签的内容;而当下一个
标签到来时,content_dict 已经是一个全新的空字典,导致前一个
标签的内容丢失,无法实现连续段落的合并。同样,在遇到
| Header 1 | Header 2 |
|---|---|
| 表格1数据A | 表格1数据B |
| 表格1数据C | 表格1数据D |
这是第三段内容。
这是第四段内容。
| Col A | Col B |
|---|---|
| 表格2数据X | 表格2数据Y |
这是第五段内容。
这是一个嵌套的段落。
这是第六段内容。
""" converter = html2text.HTML2Text() soup = BeautifulSoup(data3, 'html.parser') content_items = [] # 存储最终结果的列表 # 用于累积连续标签内容的缓冲区 current_paragraph_accumulator = [] # 为了确保处理顺序,我们通常会遍历一个共同父元素的直接子节点 # 这里假设所有相关 p 和 table 标签都是 #main-content 的直接子节点 # 如果文档结构更复杂,可能需要调整遍历策略 target_container = soup.find(id='main-content') if not target_container: # 如果没有找到特定容器,则遍历 soup 的直接子节点 # 或者根据实际HTML结构选择更合适的父元素 target_container = soup # 遍历目标容器的直接子节点,而不是所有后代,以保持内容的顺序性 for tag in target_container.children: # 忽略 NavigableString(文本节点)和非元素标签 if isinstance(tag, NavigableString) or not hasattr(tag, 'name'): continue if tag.name == "p": # 将
标签的内容添加到累加器 current_paragraph_accumulator.append(converter.handle(str(tag))) elif tag.name == "table": # 如果累加器中有内容,先将其作为一项添加 if current_paragraph_accumulator: combined_p_content = "".join(current_paragraph_accumulator).strip() if combined_p_content: # 确保内容不为空白 content_items.append({ 'Title': "35.23.060 - DR Zone Standards", 'Content': combined_p_content }) current_paragraph_accumulator = [] # 清空累加器 # 然后将当前








