聊抓取预算时,大多數人只關心一個問题:蜘蛛今天来了几次、抓了多少條。但预算其實是两個维度的乘积——抓取次數和每次抓取的成本。同一個配額下,如果你的頁面又慢又重,蜘蛛能走完的 URL 就少,剩下的時間都耗在等待和重试上。
一次抓取要经過哪几段路
從蜘蛛决定抓一個 URL,到它把頁面内容讀進自己的解析器,中間至少有這么几步:
- 解析域名,拿到 IP;
- 建立 TCP 连接,如果是 HTTPS 還要完成 TLS 握手;
- 發送請求,等待服務器返回第一個字节;
- 接收完整响應体;
- 解析 HTML,提取連結和正文;
- 如果頁面依赖 JS 渲染,還要額外下载並执行脚本。
每一段都有耗时,也都可能失敗。抓取超时通常不是發生在某一步突然坏掉,而是各段加起来超過了爬虫设定的上限。
首字节時間:服務器端的時間帳
TTFB(首字节時間)反映的是服務器從收到請求到吐出第一個字节的耗时。它慢,往往和頁面本身没關系,而是後端在等:等資料库慢查询、等缓存未命中後回源、等一個同步調用的第三方接口。
對蜘蛛来说,這段時間它什么都做不了,只能挂着连接。如果站点在抓取高峰时 TTFB 普遍拉長,表現就是蜘蛛抓取變慢、並發上不去,甚至出現大量连接超时。
几個常见的 TTFB 拖累項
- 動態頁面每次都實时查询,没有缓存层;
- 頁面头部調用了外部接口,接口慢則整頁慢;
- 日誌、統計類脚本在服務端同步寫入;
- 静態资源没有分离,静態請求也走同一套逻辑。
HTML 体积:被忽略的传輸成本
很多頁面正文只有几 KB,HTML 却有上兆。多出来的部分通常来自:直接内联進頁面的 JSON 資料、base64 编碼的图片、没有按需加载的组件样式、重复打包的脚本。
体积带来的不只是下载時間。蜘蛛要把這段 HTML 讀進内存並解析,頁面越大,單次抓取占用的资源越多,同一時間能並行的抓取就越少。
控制体积的几個方向
- 首屏需要的样式和脚本保留,其余延後;
- 資料接口不要整段内联進 HTML,改用异步請求;
- 图片走獨立的 URL,不要 base64 塞進正文;
- 開啟压缩传輸,减少實际字节數。
解析與渲染:JS 重的頁面更贵
如果正文和連結是客戶端渲染出来的,蜘蛛拿到的初始 HTML 可能几乎是空壳。它需要下载脚本、执行、再取回渲染後的内容,有时還會被排到另一個队列里延後處理。
這不代表必须全站服務端渲染。更實际的做法是分清哪些頁面必须能被抓:内容頁、分類頁、列表頁尽量服務端輸出,交互密集的頁面再交给浏览器执行。
怎么量化一個 URL 的抓取成本
- 在服務器日誌里按响應時間和响應字节數分组,看看哪些路径又慢又大;
- 用抓取工具模拟蜘蛛,记錄 TTFB、總耗时和 HTML 大小;
- 對比蜘蛛的抓取频次變化,確認優化後是否真的抓得更多;
- 重点關注返回 5xx 或超时的路径,它們最消耗重试額度。
两個常见誤区
一是只看首頁速度。首頁往往有缓存加持,真正拖後腿的是篩選頁、搜尋頁、带參數的分頁。這些頁面恰恰是蜘蛛容易大量抓到的。
二是把体积問题当成纯粹的用戶体驗問题。蜘蛛對体积的敏感度和浏览器不完全一样,它更在意能不能在限定時間内拿全内容。用戶能忍的加载動画,蜘蛛等不了。
抓取预算不是靠多提交堆出来的,而是靠把每次抓取的成本压下去省出来的。頁面轻一点、响應快一点,同样的配額就能覆盖更多 URL。