如何用BeautifulSoup获取特定class元素的前置关联元素并分组?
高效实现分组方案
核心思路
不用反复回溯查找前置元素,而是按文档顺序一次性遍历所有元素,维护一个临时列表存储当前text元素之前的关联内容,遇到text元素时直接打包成组,清空临时列表继续处理后续内容。这种方式时间复杂度为O(n),比多次调用find_all_previous/find_previous高效得多。
实现代码
from bs4 import BeautifulSoup # 替换为你的response.text html_content = """ <div id="content"> <h5>Title1</h5> <div class="text">text 1</div> <h5>Title2</h5> <h6>SubTitle</h6> <otherTag>bla bla</otherTag> <div class="text">text 2</div> <div class='pi'>post item</div> <div class="text">text 3</div> <div class="text">text 4</div> </div> """ def is_relevant_element(element): """判断是否是需要收集的关联元素""" # 匹配指定标签 if element.name in ['h5', 'h6', 'otherTag']: return True # 匹配class为pi的div if element.name == 'div' and 'pi' in element.get('class', []): return True return False soup = BeautifulSoup(html_content, 'lxml') content = soup.find('div', id='content') groups = [] current_context = [] # 遍历content下的所有元素(若只需同级元素,替换为content.children) for elem in content.descendants: # 跳过纯文本节点(避免处理换行、空格等无效内容) if not hasattr(elem, 'name'): continue # 遇到text元素时,打包当前上下文+text为一组 if elem.name == 'div' and 'text' in elem.get('class', []): # 提取上下文元素的文本,再加入当前text的文本 group = [item.get_text(strip=True) for item in current_context] group.append(elem.get_text(strip=True)) groups.append(group) # 清空上下文,准备下一组 current_context = [] # 遇到关联元素时,加入当前上下文 elif is_relevant_element(elem): current_context.append(elem) # 输出结果 for idx, group in enumerate(groups, 1): print(f"分组 {idx}: {', '.join(group)}")
运行结果
分组 1: Title1, text 1 分组 2: Title2, SubTitle, bla bla, text 2 分组 3: post item, text 3 分组 4: text 4
可选调整
如果只需要处理content的直接子元素(不需要嵌套后代),把content.descendants替换为content.children即可,进一步提升效率。
内容的提问来源于stack exchange,提问作者jdleung
相关产品推荐
相关产品推荐

