抓取本身是有時間预算的
搜尋蜘蛛抓取一個 URL 时,不會無限等待。它大致會分配一個時間预算,從建立连接、等待响應,到讀取正文和里面的連結,超出就結束這次抓取,留到以後再说。入口頁如果响應慢、传輸慢,最先受影响的就是這次抓取能否完整讀完。
需要說明的是,不同搜尋引擎、不同抓取设备的预算並不一样,也没有公開的固定秒數。所以這里讨论的是趋势,不是一條可以卡着用的及格线。
慢在哪一步,後果並不相同
1. 建立连接和首字节時間過慢
如果服務器在很長一段時間里都没有返回狀態碼,蜘蛛可能在收到响應之前就断開。這種情况在日誌里常常表現為請求有记錄、但没有完整的响應狀態,或者反复重试。
2. 正文传輸太慢或体积過大
响應头正常,但 HTML 体积很大、又没有開啟压缩,蜘蛛讀到一半就可能停下。此时頁面後半部分的連結不會被處理,放在後面的目标 URL 也就等于没寫。
3. 連結依赖脚本渲染
普通的图片、样式、字体拖慢加载,一般不影响連結發現;但如果目标 URL 是脚本执行後才插入到頁面里的,脚本没跑完或超时,連結就不會出現。
連結的位置會被速度問题放大
同样是慢,連結放在 HTML 靠前和靠後,结果差別很明顯。前面是一大段内联脚本或样式、目标連結堆在後面的入口頁,在慢速场景下更容易出現“頁面被抓了、連結却没被發現”的情况。
- 把目标連結尽量放在 HTML 靠前的位置
- 减少 head 里的阻塞脚本和大量内联样式
- 避免依赖脚本拼接後再渲染連結
- 控制單頁 HTML 体积,重复结构不要硬堆
慢响應還會影响之後几次抓取
一次超时通常不會永久封死入口頁,但可能带来连鎖反應:蜘蛛對這個地址的抓取频次下降,重试間隔被拉長,同一批入口頁的發現节奏也會整体變慢。如果同一台服務器上的多個入口頁都很慢,表現會更集中。
慢不一定等于蜘蛛不来,但會让它在有限的抓取预算里,更少地讀完你的頁面。
怎么判断問题是速度引起的
- 看服務器日誌里蜘蛛請求的响應時間,重点關注明顯偏長和没有正常狀態碼的請求。
- 用命令行工具记錄首字节時間和總耗时,例如比較 time_starttransfer 與 time_total。
- 把同一批入口頁按快慢分成两组,观察目标 URL 被抓取的比例是否有明顯差异。這只是观察,不能当成嚴格的因果结论。
- 临时精简某個入口頁,再對比它前後几天的抓取记錄。
可以着手做的几件事
- 開啟 gzip 或 brotli 压缩,减少正文传輸量。
- 入口頁走缓存或 CDN,避免每次請求都回源做重查询。
- 把資料库查询、外部接口調用從入口頁的渲染路径里移出去。
- 保持稳定返回 200,避免長時間 5xx 或反复跳轉鏈。
- 如果入口頁是程序動態生成的,注意生成逻辑本身耗时,別让它比網絡传輸還慢。
两個容易走偏的方向
一種是觉得“内容越多越好”,把大量脚本、統計代碼、外部资源全塞進入口頁,结果把抓取预算消耗在無關内容上;另一種是矫枉過正,把入口頁做成几乎空白的跳轉頁,連結虽然靠前,但頁面本身缺乏可用信息,抓取價值不高。
比較稳妥的做法是:让入口頁保持轻、快、稳定,把目标連結放在顯眼且靠前的位置,然後用日誌持續观察目标 URL 的發現情况,按資料調整,而不是一次改完就当作已经解决。