讨论抓取效率时,很多人只看“蜘蛛来了多少次”,却忽略了每次抓取本身的成本构成。在同样的抓取窗口下,一個响應慢、体积大的頁面,會占掉另一個轻量頁面好几倍的時間。把這两件事拆開看,能解释不少“抓取量没少,但新頁面迟迟不来”的現象。
一次抓取的時間是怎么用掉的
蜘蛛的一次請求,大致可以拆成三段:建立连接並等待响應、传輸响應体、解析並提取連結。第三段發生在蜘蛛自己那一侧,站点能影响的主要是前两段。而前两段里,真正被站点掌控的指标其實只有两個:首字节時間(TTFB)和响應体大小。
首字节時間包含排队
TTFB 不是單纯的“服務器算得快不快”。它里面還混着 DNS 解析、TCP 握手、TLS 握手、請求進入服務器後的等待队列、應用框架初始化、資料库或缓存的第一次查询。動態頁面尤其明顯,一個没命中缓存的請求,光初始化就可能吃掉几百毫秒,而蜘蛛在同一個域名上並不會開無限並發去等它。
体积則决定传輸那一段
HTML 本身通常不大,但不少站点會把大量資料内联進頁面:整本书的 JSON、全量配置、几十 KB 的 base64 占位图。蜘蛛把這些字节讀進来,却只會用其中一小部分来做連結發現。多出来的部分,等于让蜘蛛花時間搬运它並不需要的東西。
抓取预算不是一個抽象概念,它由“每個 URL 消耗多少時間”乘以“可用的抓取窗口”决定。降低單次成本,相当于放大整個窗口的容量。
服務器稳定,指的是波動小
“稳定”容易被理解成“不宕机”。對蜘蛛来说,更關键的是响應時間的抖動。一個平均 200ms、但偶尔飙到 5s 的接口,會让蜘蛛在多次超时後主動降速;而降速之後,恢复往往是渐進的。相比之下,一個始终稳定在 400ms 的站点,抓取节奏反而更容易维持。
- 同一類頁面的响應時間差异不要過大,避免個別頁面拖慢整批队列;
- 控制同时處理的動態請求數,宁可排队也不要让進程互相抢资源;
- 静態资源與 HTML 分開處理,別让图片請求占满應用進程。
把成本花在“能被發現的東西”上
减少單次抓取成本,最直接的收益是連結發現變多。可以從几個简單方向入手:
- 開啟文本压缩,HTML 传輸体积通常能明顯下降;
- 给列表頁和詳情頁做缓存,让 TTFB 稳定在一個可预期的区間;
- 把内联的大块資料移到按需加载的接口里,HTML 只保留结构與連結;
- 检查是否有頁面在返回完整内容前做了多次串行查询。
怎么做一次简單的對照
不用复杂工具也能看個大概:從日誌里挑出同一個模板下的若干 URL,观察它們被抓取的時間間隔,或者看抓取频率在某個時間段的變化。如果某一批 URL 的抓取明顯稀疏,而它們恰好是响應最慢或体积最大的那批,那么優先優化成本,比繼續加内鏈更直接。
最後提醒一句:抓取效率的優化,是让蜘蛛的每一次到訪都更有收获,而不是想办法让它来得更勤。前者站点可以控制,後者不由站点说了算。