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

如何将Python链接爬虫从深度优先改为广度优先遍历?

如何将基于BeautifulSoup的深度优先网页爬虫改为广度优先遍历?

我有一个网站结构如下:

  • http://example.com/home 包含指向 /page1、/page2、/page3 的链接
  • http://example.com/page1 包含指向 /page2368 的链接
  • http://example.com/page2 包含指向 /page41 的链接
  • http://example.com/page2368 包含指向 /page999990 到 /page999999 的链接

目前我用下面这段基于BeautifulSoup的Python代码做链接爬取,它是深度优先遍历(DFS)的,会先走完 /home → /page1 → /page2368 → /page999990 这条线,之后才会去访问 /page2:

from bs4 import BeautifulSoup
def visit(url, recursion=0):
    links = getpage_and_retrieve_ahref_links(url) # using beautifulsoup
    for link in links:
        if recursion < 10: # limit recursion to 10
            visit(link, recursion+1)
visit('http://example.com/home')

我需要把它改成广度优先遍历(BFS),也就是先爬完所有recursion=1层级的页面(/page1、/page2、/page3),再爬recursion=2层级的(/page2368、/page41),以此类推,访问顺序应该是:/home → /page1 → /page2 → /page3 → /page2368 → /page41 → /page999990... 请问该怎么修改代码?


核心思路:用队列替代递归

咱们先理清楚本质:深度优先遍历(DFS)靠的是递归的“栈”特性(后进先出),会一条路走到头再回头;而广度优先遍历(BFS)需要队列(先进先出)来管理待爬的URL,先把当前层级的所有页面都处理完,再去处理下一层级的内容。

Python的collections.deque是实现队列的绝佳选择,它的popleft()操作是O(1)的,比用列表模拟队列高效得多。

修改后的代码

from bs4 import BeautifulSoup
from collections import deque

def bfs_crawl(start_url, max_depth=10):
    # 初始化队列,每个元素是(当前URL, 当前层级)
    queue = deque()
    queue.append((start_url, 0))
    
    # 可选:记录已访问的URL,避免重复爬取(根据需求选择是否添加)
    visited = set()
    visited.add(start_url)
    
    while queue:
        current_url, depth = queue.popleft()
        
        # 处理当前页面:获取所有链接
        links = getpage_and_retrieve_ahref_links(current_url)
        
        # 如果当前层级还没到最大限制,就把新链接加入队列
        if depth < max_depth:
            for link in links:
                # 可选:跳过已访问的链接
                if link not in visited:
                    visited.add(link)
                    queue.append((link, depth + 1))

# 启动爬虫
bfs_crawl('http://example.com/home')

关键细节说明

  1. 队列的作用:每次从队列头部取出最早上加入的URL(当前层级的页面),爬完后把它的子链接(下一层级)加到队列尾部,完美实现“先爬完当前所有层级,再爬下一层”的BFS逻辑。
  2. 层级管理:用(url, depth)的元组替代原来的递归参数,清晰记录每个页面的层级,确保不会超过你设置的最大深度限制。
  3. 去重优化:添加visited集合是为了避免重复爬取同一个URL(比如不同页面指向同一个链接的情况),如果你的网站没有重复链接,也可以去掉这部分,但建议保留以提升爬虫效率。
  4. 替代递归的优势:BFS用迭代+队列实现,不仅更符合遍历逻辑,还能避免递归深度过大导致的栈溢出问题(比如如果你的层级限制不是10而是100,递归大概率会报错)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:46:04