如何用BeautifulSoup解析树形网页提取叶子节点及上级代码?
嘿,这个问题其实不用费劲去解析DOM里的树形结构——页面里已经给你准备好了结构化的数据源!就是那个dataSet数组,jstree就是靠它渲染出来的,直接用这个数据会简单太多了,我给你一步步讲怎么弄:
解决方案:直接提取页面中的jstree数据源
步骤1:提取并解析dataSet的JSON数据
首先我们要把script标签里的dataSet内容抠出来,转成Python能处理的结构:
import re import json from bs4 import BeautifulSoup # 假设你已经获取到网页内容并存入了html_content变量 soup = BeautifulSoup(html_content, 'lxml') # 找到包含dataSet定义的script标签 script_tag = soup.find('script', text=re.compile('var dataSet =')) # 用正则提取出数组部分的JSON字符串(去掉var定义和末尾分号) json_match = re.search(r'var dataSet = (\[.*?\]);', script_tag.string, re.DOTALL) json_str = json_match.group(1) # 解析成Python列表 node_data = json.loads(json_str)
步骤2:构建节点映射表
为了快速查找每个节点的父节点信息,我们把节点id作为键,整个节点对象作为值,建一个字典:
node_map = {node['id']: node for node in node_data}
步骤3:筛选叶子节点并提取目标信息
根据你给的示例,叶子节点是type为"pl"的节点(比如那个ho15744节点)。我们遍历这些节点,提取你需要的内容:
# 筛选所有type为pl的叶子节点 leaf_nodes = [node for node in node_data if node.get('type') == 'pl'] # 整理结果 final_results = [] for leaf in leaf_nodes: # 获取直接父节点的id parent_code = leaf['parent'] # 处理节点文本:去掉末尾的(referral)并清理空格 clean_leaf_name = re.sub(r'\s*\(referral\)$', '', leaf['text']).strip() final_results.append({ '药品名称': clean_leaf_name, '上级代码': parent_code }) # 可以打印几个示例看看效果 for item in final_results[:5]: print(f"名称: {item['药品名称']}, 上级代码: {item['上级代码']}")
备选方案:通过子节点判断叶子
如果有些叶子节点的type不是pl,你也可以通过节点没有子节点来判断:
# 收集所有作为父节点的id(除了根节点的#) all_parent_ids = {node['parent'] for node in node_data if node['parent'] != '#'} # 叶子节点就是id不在父节点集合里的节点 leaf_nodes = [node for node in node_data if node['id'] not in all_parent_ids]
这样处理后,你就能拿到所有叶子节点的名称和它们的直接上级代码,完全满足你的需求啦!
内容的提问来源于stack exchange,提问作者Lusian
相关产品推荐
相关产品推荐

