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

如何实现递归函数提取Beautiful Soup列表标签下的直接文本?

如何实现递归函数提取Beautiful Soup列表标签下的直接文本?

嘿,我来帮你把这个递归函数的蓝图打磨成可用的代码!你想要处理嵌套的<ul>/<ol>标签,提取每个<li>里的文本并保留嵌套结构对吧?先梳理下你原思路里的小问题,再给出调整后的完整实现:

先修正原蓝图里的几个小问题

  • list是Python内置关键字,不能用作变量名,得换成current_list这类合法名称
  • 循环遍历要精准定位当前列表的直接子<li>,避免深层嵌套元素干扰
  • 判断元素是否包含子列表,要通过Beautiful Soup的查找方法,而非直接判断类型
  • 提取文本时要过滤掉子列表里的内容,只保留当前<li>的直接文本节点

完整实现代码

from bs4 import BeautifulSoup

def extract_list_items(current_list):
    items = []
    # 只遍历当前列表的直接子li标签,不递归查找深层li
    for li in current_list.find_all('li', recursive=False):
        # 提取当前li下的直接文本(排除子列表里的文本),清理多余空格换行
        direct_text = ''.join([text.strip() for text in li.find_all(text=True, recursive=False)]).strip()
        # 检查当前li是否包含嵌套的ul/ol列表
        nested_list = li.find(['ul', 'ol'])
        
        if nested_list:
            # 既有直接文本又有嵌套列表:将文本与递归结果组合
            if direct_text:
                items.append([direct_text, extract_list_items(nested_list)])
            # 只有嵌套列表无直接文本:直接添加递归结果
            else:
                items.append(extract_list_items(nested_list))
        else:
            # 无嵌套列表:清理后文本非空才添加
            if direct_text:
                items.append(direct_text)
    return items

代码关键逻辑说明

  • recursive=False:这个参数是核心,不管是查找<li>还是文本节点,都只处理当前节点的直接子元素,避免提前提取深层嵌套内容
  • 文本清理:通过列表推导式拼接所有直接文本节点,再用strip()去除多余空格和换行,保证输出文本整洁
  • 嵌套处理:遇到子列表时递归调用函数,根据当前<li>是否有直接文本,决定是组合文本与子列表结果,还是单独添加子列表结果

用你的示例测试

拿你给出的HTML列表测试:

<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>
        Item 3
        <ul>
            <li>Subitem 1</li>
            <li>Subitem 2</li>
        </ul>
        Item 3.1
    </li>
</ul>

测试代码:

html = """
<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>
        Item 3
        <ul>
            <li>Subitem 1</li>
            <li>Subitem 2</li>
        </ul>
        Item 3.1
    </li>
</ul>
"""

soup = BeautifulSoup(html, 'html.parser')
main_list = soup.find('ul')
result = extract_list_items(main_list)
print(result)

输出结果:

['Item 1', 'Item 2', ['Item 3Item 3.1', ['Subitem 1', 'Subitem 2']]]

额外说明

  • 代码同时支持<ul>和<ol>标签,无需额外修改
  • 如果需要保留<li>中子列表前后文本的分隔(比如把Item 3和Item 3.1分开),可以调整direct_text的生成逻辑,改成收集非空文本片段的列表
  • 空的<li>(无文本也无子列表)会被自动跳过,不会出现在结果里

备注:内容来源于stack exchange,提问作者Amjuks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 08:58:00