如何用Python和BeautifulSoup提取City<p>标签下的嵌套文本?
解决方案:提取City标签后的嵌套文本内容
核心思路
- 定位所有class为
indented的div元素 - 在每个div里找到内容为"City"的最后一个p标签
- 遍历该p标签之后的所有兄弟节点,递归提取每个节点的文本,同时保留粗体、斜体等格式,忽略图片类非文本元素
代码实现示例
from bs4 import BeautifulSoup, Tag def extract_formatted_text(node): """递归提取节点文本,保留粗体、斜体格式""" if not isinstance(node, Tag): return node.strip() if node else "" # 忽略图片标签 if node.name == 'img': return "" # 处理格式标签 text_parts = [] for child in node.children: child_text = extract_formatted_text(child) if child_text: text_parts.append(child_text) # 给粗体、斜体添加markdown格式 if node.name == 'b' or node.name == 'strong': return f"**{' '.join(text_parts)}**" elif node.name == 'i' or node.name == 'em': return f"*{' '.join(text_parts)}*" elif node.name in ['ul', 'ol']: # 处理列表,每个列表项加-前缀 list_items = [] for li in node.find_all('li', recursive=False): li_text = extract_formatted_text(li) if li_text: list_items.append(f"- {li_text}") return '\n'.join(list_items) elif node.name == 'li': return ' '.join(text_parts) else: # 普通标签直接拼接文本 return ' '.join(text_parts) def get_city_related_content(html_content): soup = BeautifulSoup(html_content, 'html.parser') results = [] # 遍历所有indented类的div for indented_div in soup.find_all('div', class_='indented'): # 找到内容为"City"的p标签(最后一个符合的) city_p = None for p in indented_div.find_all('p'): if p.get_text(strip=True) == 'City': city_p = p if not city_p: continue # 提取city_p之后的所有兄弟节点内容 content_parts = [] for sibling in city_p.next_siblings: if isinstance(sibling, Tag) and sibling.parent != indented_div: break # 超出当前div范围,停止遍历 sibling_text = extract_formatted_text(sibling) if sibling_text: content_parts.append(sibling_text) if content_parts: results.append('\n\n'.join(content_parts)) return results
代码说明
extract_formatted_text函数递归处理每个节点,自动将<b>/<strong>转换为markdown粗体,<i>/<em>转换为斜体,列表元素转换为markdown无序列表,同时忽略<img>标签。get_city_related_content函数负责定位目标div和City标签,然后遍历其后的所有兄弟节点,收集并整理文本内容。- 遍历兄弟节点时,会检查节点的父元素是否为当前的
indenteddiv,避免提取到div外部的内容。
内容的提问来源于stack exchange,提问作者nb123
相关产品推荐
相关产品推荐

