You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Beautiful Soup爬取网站菜单栏的多层级结构?

解决导航栏层级爬取问题

原代码的问题很明确:它直接把每个一级菜单项下的所有文本一股脑塞进同一个列表,完全没处理导航栏的嵌套结构——那些带下拉子菜单的项,子菜单文本被和一级标题的附属文本混在一起,自然会出现重复、层级丢失的问题。

要保留导航栏的层级结构,得用递归方式遍历每个菜单项,识别子菜单并逐层构建嵌套字典/列表,改进后的代码如下:

from bs4 import BeautifulSoup as bs
import requests
import json

def parse_menu_item(li):
    # 获取当前菜单项的标题文本
    title = next(li.stripped_strings)
    # 查找当前项的直接子菜单(不递归查找深层)
    sub_menu = li.find('ul', recursive=False)
    
    if sub_menu:
        sub_items = {}
        # 遍历子菜单里的每个菜单项
        for sub_li in sub_menu.find_all('li', recursive=False):
            sub_title, sub_content = parse_menu_item(sub_li)
            # 根据子项类型整理结构
            if sub_content:
                sub_items[sub_title] = sub_content
            else:
                # 处理无下级子菜单的单个项
                sub_items[sub_title] = []
        return title, sub_items
    else:
        # 当前项没有子菜单,返回标题和空列表标记
        return title, []

url = 'https://www.trumpf.com/en_IN/'
html_text = requests.get(url).text
soup = bs(html_text, 'html.parser')

# 定位导航栏的根菜单
nav_root = soup.select_one('nav > ul')
final_menu = {}

# 遍历根菜单的每个一级项
for li in nav_root.find_all('li', recursive=False):
    item_title, item_content = parse_menu_item(li)
    final_menu[item_title] = item_content

# 格式化输出结果
print(json.dumps(final_menu, indent=2))

代码说明

  • 核心是parse_menu_item递归函数:每个菜单项先提取标题,再检查是否存在直接子菜单;
  • 若有子菜单,就递归处理每个子项,把结果整理成嵌套字典;若无子菜单,则标记为叶子节点;
  • 这样能完整还原导航栏的层级关系,不会出现文本混杂、重复的问题。

内容的提问来源于stack exchange,提问作者Rovsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:30:44