bigywater.tech
爬虫工程 · 29

抓取顺序:BFS、DFS、优先级队列的覆盖率对比

爬虫的待抓队列用先进先出、后进先出还是优先级队列,决定了在预算有限时先抓到什么。这篇用一个自己造的合成站点,量化三种顺序在不同预算下抓到多少有价值的页面、待抓队列有多大、遇到“标签云”这样的低价值团簇会浪费多少。

93 / 33 / 15
预算 100 页时,优先级策略 / DFS / BFS 抓到的商品页数(共 6000 个)
270 / 72
抓满全站时,BFS 与 DFS 待抓队列的峰值
61 对 0
预算 300 页里 BFS/DFS 与优先级策略花在低价值标签云上的页数

合成站点

实测 · 本机执行输出
  策略                            预算  100   预算  300   预算 1000   预算 3000   预算 6000   
  BFS(先进先出,按层)                    15/6000     205/6000     872/6000    2777/6000    5634/6000
  DFS(后进先出)                       33/6000     223/6000     889/6000    2791/6000    5643/6000
  优先级:先商品页再列表                     93/6000     283/6000     949/6000    2851/6000    5703/6000
  优先级:深度小的先(≈BFS)                 15/6000     205/6000     872/6000    2777/6000    5634/6000
  (商品页共 6000 个,全站 6374 个页面;预算 6374 时三种策略最终都会抓完)

这是我自己写的链接图,不是真实网站:首页 → 10 个分类 → 每个分类 30 个分页列表页 → 每页 20 个商品页(共 6000 个商品页),另有一团 60 页互相链接的“标签云”和几个导航页。所有结论只对这个图成立。

预算有限时顺序最重要

实测 · 本机执行输出
  BFS(先进先出,按层):待抓队列峰值 270
  DFS(后进先出):待抓队列峰值 72
  优先级:先商品页再列表:待抓队列峰值 60
  优先级:深度小的先(≈BFS):待抓队列峰值 270

预算 100 页:BFS 15、DFS 33、按 URL 模式优先抓商品页 93;预算 1000 页:872 / 889 / 949。预算越小策略越重要,接近全站大小时差别消失。注意优先级策略利用了“商品页 URL 以 /item/ 开头”这个事先知道的信息,真实站点里要靠规则或学习得到。

队列大小

实测 · 本机执行输出
  BFS(先进先出,按层):预算 300 时抓到商品页 205
  DFS(后进先出):预算 300 时抓到商品页 223
  优先级:先商品页再列表:预算 300 时抓到商品页 283
  预算 300 里花在标签云上的页数:BFS 61,DFS 61,优先级 0

BFS 的待抓队列随一层的宽度增长(峰值 270),DFS 沿一条路径深入、队列小(72)。优先级策略如果只按深度排,等价于 BFS(队列峰值也是 270)。

陷阱与链接顺序

实测 · 本机执行输出
  / → /tags → /tag/59 → /tag/58 → /tag/57 → /tag/56 → /tag/55 → /tag/54 → /tag/53 → /tag/52 → /tag/51 → /tag/50 → /tag/49 → /tag/48 → /tag/47

互相链接的低价值页面团簇会吃掉预算:BFS 与 DFS 在 300 页预算里各花了 61 页。DFS 的路径依赖首页链接的顺序,同一个站点换个链接顺序,结果可能不同;这里只用了一种顺序。

分步演示

抓取顺序
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / requests 2.34.2 / aiohttp 3.14.3 / lxml 6.1.1(系统 Python);所有请求只发给本机自己起的测试服务器(127.0.0.1,端口 9960 以上,不访问任何真实网站);服务器可以按实验需要制造延迟、断连、压缩、重定向等行为,并记录收到的原始请求;计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇不发网络请求:用 Python 的 deque(BFS)、list 当栈(DFS)、heapq(优先级,同优先级先发现先抓)在内存里的合成链接图上模拟抓取;每抓一个页面计 1 次预算,抓到的商品页数累计;合成图的构造见实验脚本(固定构造,没有随机成分)
    • 没有验证:真实站点的链接结构(商品页常通过搜索、推荐互相链接,不是一棵树);链接顺序不同的图上的 DFS;带有重复内容或无限分页的陷阱(下面有专门的文章);学习型优先级(根据已抓结果调整);每个页面抓取耗时不同时的效果;去重和 URL 规范化对队列大小的影响(下面也有专门的文章)
    京ICP备2026067502号-1京公网安备11010502063487号