讨论抓取效率时,很多人只看“蜘蛛来了多少次”,却忽略了每次抓取本身的成本构成。在同样的抓取窗口下,一个响应慢、体积大的页面,会占掉另一个轻量页面好几倍的时间。把这两件事拆开看,能解释不少“抓取量没少,但新页面迟迟不来”的现象。
一次抓取的时间是怎么用掉的
蜘蛛的一次请求,大致可以拆成三段:建立连接并等待响应、传输响应体、解析并提取链接。第三段发生在蜘蛛自己那一侧,站点能影响的主要是前两段。而前两段里,真正被站点掌控的指标其实只有两个:首字节时间(TTFB)和响应体大小。
首字节时间包含排队
TTFB 不是单纯的“服务器算得快不快”。它里面还混着 DNS 解析、TCP 握手、TLS 握手、请求进入服务器后的等待队列、应用框架初始化、数据库或缓存的第一次查询。动态页面尤其明显,一个没命中缓存的请求,光初始化就可能吃掉几百毫秒,而蜘蛛在同一个域名上并不会开无限并发去等它。
体积则决定传输那一段
HTML 本身通常不大,但不少站点会把大量数据内联进页面:整本书的 JSON、全量配置、几十 KB 的 base64 占位图。蜘蛛把这些字节读进来,却只会用其中一小部分来做链接发现。多出来的部分,等于让蜘蛛花时间搬运它并不需要的东西。
抓取预算不是一个抽象概念,它由“每个 URL 消耗多少时间”乘以“可用的抓取窗口”决定。降低单次成本,相当于放大整个窗口的容量。
服务器稳定,指的是波动小
“稳定”容易被理解成“不宕机”。对蜘蛛来说,更关键的是响应时间的抖动。一个平均 200ms、但偶尔飙到 5s 的接口,会让蜘蛛在多次超时后主动降速;而降速之后,恢复往往是渐进的。相比之下,一个始终稳定在 400ms 的站点,抓取节奏反而更容易维持。
- 同一类页面的响应时间差异不要过大,避免个别页面拖慢整批队列;
- 控制同时处理的动态请求数,宁可排队也不要让进程互相抢资源;
- 静态资源与 HTML 分开处理,别让图片请求占满应用进程。
把成本花在“能被发现的东西”上
减少单次抓取成本,最直接的收益是链接发现变多。可以从几个简单方向入手:
- 开启文本压缩,HTML 传输体积通常能明显下降;
- 给列表页和详情页做缓存,让 TTFB 稳定在一个可预期的区间;
- 把内联的大块数据移到按需加载的接口里,HTML 只保留结构与链接;
- 检查是否有页面在返回完整内容前做了多次串行查询。
怎么做一次简单的对照
不用复杂工具也能看个大概:从日志里挑出同一个模板下的若干 URL,观察它们被抓取的时间间隔,或者看抓取频率在某个时间段的变化。如果某一批 URL 的抓取明显稀疏,而它们恰好是响应最慢或体积最大的那批,那么优先优化成本,比继续加内链更直接。
最后提醒一句:抓取效率的优化,是让蜘蛛的每一次到访都更有收获,而不是想办法让它来得更勤。前者站点可以控制,后者不由站点说了算。