Python爬虫:如何用BeautifulSoup将嵌套ul/li转为多层字典/列表?
如何将嵌套HTML列表转换为多层Python字典?
你遇到的这个嵌套列表转字典的问题,用递归来处理是最简便高效的,因为嵌套结构本身就适合递归遍历。我帮你梳理一下实现思路和代码:
首先,你给的示例字典存在语法小问题(字典里不能直接嵌套无键的字典),我会给你一个语法合法且结构清晰的实现,你可以根据需求调整。
实现代码
在你现有代码的基础上,添加一个递归处理函数即可:
from bs4 import BeautifulSoup from urllib.request import Request, urlopen import pprint # 用来格式化打印结果,方便查看层级结构 req = Request("https://my.site.com/crawl", headers={'User-Agent': 'Mozilla/5.0'}) webpage = urlopen(req) soup = BeautifulSoup(webpage, 'html.parser') ul = soup.find('ul', {'class': ''}) def parse_nested_list(ul_element): result_dict = {} # 只遍历当前ul的直接子li,避免递归时重复处理子层级的li for li in ul_element.find_all('li', recursive=False): # 定位li里的目标a标签 a_tag = li.find('a', class_='reference') if not a_tag: continue # 跳过没有a标签的li(如果存在的话) # 提取文本:自动处理带span的情况,strip去除多余空格 item_text = a_tag.get_text(strip=True) # 提取href:去掉开头的#,和你示例里的格式匹配 item_href = a_tag['href'].lstrip('#') # 构建当前条目的基础信息 current_item = {'href': item_href} # 检查当前li是否包含直接子ul(子列表) sub_ul = li.find('ul', recursive=False) if sub_ul: # 递归处理子列表,将结果存入current_item的children键下 current_item['children'] = parse_nested_list(sub_ul) # 将当前条目加入结果字典 result_dict[item_text] = current_item return result_dict # 调用函数生成最终层级字典 final_result = parse_nested_list(ul) # 格式化打印结果,方便查看 pprint.pprint(final_result)
代码说明
- 递归核心逻辑:函数
parse_nested_list会处理传入的<ul>元素,遍历它的直接子<li>;如果某个<li>里还有子<ul>,就递归调用自己处理子列表,自然形成嵌套结构。 - 避免重复遍历:用
recursive=False参数确保只处理当前层级的元素,不会深入到子列表里重复处理,这是保证层级正确的关键。 - 文本和href处理:
get_text(strip=True)自动兼容了带<span>的文本情况,lstrip('#')把href里的#去掉,完全匹配你想要的格式。 - 合法的字典结构:用
children键存放子层级内容,既保证语法合法,也让结构更清晰,方便后续的遍历或修改操作。
运行后你会得到类似这样的规范结构:
{ 'Data1': {'href': 'ref1'}, 'Data2': { 'href': 'ref2', 'children': { 'Data3': {'href': 'ref3'}, 'Data4': { 'href': 'ref4', 'children': { 'Data5': {'href': 'ref5'}, 'Data6': {'href': 'ref6'} } } } }, 'Data7': { 'href': 'ref7', 'children': { 'Data8': {'href': 'ref8'}, 'Data9': {'href': 'ref9'} } }, 'Data10': { 'href': 'ref10', 'children': { 'Data11': {'href': 'ref11'}, 'Data12': {'href': 'ref12'} } } }
如果一定要和你示例里的结构完全一致(虽然语法不合法),可以调整逻辑把子项直接合并到当前字典,但这样容易出现键冲突(比如子项名称和href冲突),所以更推荐用children键的规范结构。
内容的提问来源于stack exchange,提问作者magnusnn
相关产品推荐
相关产品推荐

