蜘蛛抓一個 URL,日誌里往往只留下一行记錄,看起来是一次很简單的請求。但從它决定訪問到拿到完整的 HTML,中間要经過好几個环节:解析域名、建立连接、發起請求、等待响應、传輸正文。任何一环出問题,這次抓取就中断了。而中断的次數,會直接影响一個站点被發現的效率。
一次抓取要经過哪些环节
- DNS 解析:把域名換成 IP,缓存失效时會額外增加耗时。
- 建立连接與握手:TCP 三次握手,如果是 HTTPS 還要加上 TLS 协商。
- 發送請求、等待响應头:這一段主要看服務器什么时候開始處理。
- 接收正文:頁面越大、動態生成越慢,這一段越長。
其中耗时最長、也最不可控的,是服務器處理請求的那一段。蜘蛛的等待時間有上限,超過上限它就會放弃這次抓取,把资源留给別的 URL。
三種常见的抓取中断
响應超时
服務器迟迟不返回任何内容,蜘蛛等到超时後断開。常见原因是慢查询、外部接口阻塞、模板渲染耗时過長。它不一定會报错,只是這次抓取白跑一趟。
服務端 5xx
服務器明确表示自己出了問题,比如 500、502、503。蜘蛛會把它当作临时故障,而不是頁面消失。但如果连續几天都是 5xx,抓取频率就會被压低。
连接被拒或重置
防火墙拦截、並發限流、连接數打满,都可能让蜘蛛在握手阶段就被拒。這類失敗在日誌里常常只有一行连接错誤,不太顯眼,但影响和超时類似。
中断之後會發生什么
- 蜘蛛通常會重试几次,而不是立刻放弃這個 URL。
- 如果同一個主机上连續多次失敗,该主机的整体抓取速度會被压低,這是一道自我保護机制。
- 已经被收錄的頁面不會因為一次超时就掉出索引,但更新會延後,直到下一次成功回訪。
- 失敗的 URL 會被推回队列,深頁本来就抓取優先級低,一旦失敗,回訪間隔會被拉得更長。
一次超时是偶然,一批超时是信号。前者不用管,後者需要查。
哪些中断其實可以避免
- 让响應時間保持稳定。真實情况是波動的,但不要出現大量請求同时卡住的情况,尤其是資料库压力最大的时段。
- 限流要温和。宁可返回 429 並带上 Retry-After,也不要直接断開连接,後者對蜘蛛来说更难判断。
- 5xx 只用于真正的临时故障。如果某個栏目已经下线,返回 404 或 410 比一直报 500 更清楚。
- 消耗大的頁面尽量做缓存。同一份内容在短時間内被多次請求,没必要每次重新計算。
- 给蜘蛛留出带宽余量。日誌里抓取請求和真實用戶請求混在一起时,很难判断是谁把服務器压住的。
怎么確認問题出在哪
先看抓取日誌里的响應時間分布,不要只看平均值。中位數正常、尾部很長,說明有少數請求卡住了,這類情况對蜘蛛的体驗同样不好。接着對比不同爬虫的抓取統計,如果只有某一個来源失敗率偏高,問题更可能出在鏈路或拦截規則上;如果所有来源都在失敗,那就是站点本身。
抓取路径能否走通,靠的不是某一次抓取多快,而是它在大多數时候都能顺利完成。稳定比快更重要。