如何用BeautifulSoup遍历HTML的<hr>标签提取对应内容?
问题分析与解决方法
重复提取的核心原因
- 代码每次提取
<li>时,都是从整个HTML文档的根节点(比如用soup.find('li')或soup.select_one('li'))全局查找,而非限定在当前<hr>标签的后续区域内,导致每次循环都拿到文档中第一个匹配的<li>。 - 未正确定位每个
<hr>对应的后续节点范围,始终在全局范围内查询目标元素。
正确实现思路与代码
核心逻辑
先遍历所有<hr>标签,再针对每个<hr>,仅在其后续相邻区域内查找<li>元素,避免全局查询。
示例代码
假设HTML结构如下:
<hr> <ul> <li><b>分类A</b>:日常工具</li> <li><b>分类B</b>:开发资源</li> </ul> <hr> <ul> <li><b>分类C</b>:设计素材</li> </ul>
对应Python实现:
from bs4 import BeautifulSoup # 替换为你的页面HTML内容 html = """ <!-- 此处为目标HTML代码 --> """ soup = BeautifulSoup(html, 'html.parser') # 遍历所有<hr>标签 for hr in soup.find_all('hr'): # 定位当前<hr>后的第一个列表容器<ul> target_list = hr.find_next('ul') if not target_list: continue # 仅在当前<ul>内遍历<li> for li in target_list.find_all('li'): # 提取<b>标签内的文本 bold_text = li.find('b').get_text(strip=True) # 提取<li>末尾的剩余文本(去除<b>内容后) full_li_text = li.get_text(strip=True) end_text = full_li_text.replace(bold_text, '', 1).strip().lstrip(':') # 根据实际HTML结构调整分隔符 print(f"加粗标题:{bold_text},描述内容:{end_text}")
如果<li>未被<ul>包裹,直接作为<hr>的兄弟节点,可改用兄弟节点遍历:
for hr in soup.find_all('hr'): # 遍历<hr>之后的所有<li>兄弟节点,直到遇到下一个<hr>停止 for li in hr.find_next_siblings('li'): next_node = li.find_next_sibling() if next_node and next_node.name == 'hr': break # 提取内容逻辑同上 bold_text = li.find('b').get_text(strip=True) full_li_text = li.get_text(strip=True) end_text = full_li_text.replace(bold_text, '', 1).strip() print(f"加粗标题:{bold_text},描述内容:{end_text}")
内容的提问来源于stack exchange,提问作者qLu
相关产品推荐
相关产品推荐

