搜尋抓取

從 DNS 到首字节:蜘蛛請求一個 URL 时,哪一步最容易卡住

蜘蛛抓取一個 URL,在拿到 HTML 之前要经過 DNS 解析、TCP 连接、TLS 握手、首字节返回和响應体传輸。這些环节不产生任何内容,却直接决定抓取能否成功。本文按顺序拆解每個环节的常见故障表現,並给出用日誌和抓取統計對照排查的方法,帮助把問题定位在正确的层次上。

搜尋抓取

從 DNS 到首字节:蜘蛛請求一個 URL 时,哪一步最容易卡住

很多人排查抓取問题,习惯從内容层面入手:内鏈够不够、Sitemap 全不全、頁面有没有重复。但蜘蛛能不能拿到頁面,第一步其實發生在内容之前——它得先把請求發出去,並且完整地收到响應。這一段鏈路里任何一环出問题,反映到抓取統計上都是“抓取量下降”,可原因完全不同。

一次抓取要走的几步

把蜘蛛当成一個普通的 HTTP 客戶端,它訪問一個 URL 大致會经過這些环节:

  • DNS 解析:把域名換成 IP 地址
  • 建立 TCP 连接:握手、選定端口
  • TLS 握手:HTTPS 站点协商加密參數、校驗證书
  • 發送 HTTP 請求,带上路径、头部和蜘蛛标识
  • 服務器處理請求,生成响應
  • 返回首字节
  • 传輸响應体,直到最後一個字节
  • 解析内容、提取連結,進入下一轮队列

其中前面几步是“不产生頁面内容”的纯開销。它們快,蜘蛛就能在同样的時間里多抓几個頁面;它們慢或者失敗,蜘蛛连内容都看不到。

容易卡住的几個环节

DNS 解析

DNS 是最容易被忽略的一环。它通常很快,但一旦出問题,影响面比服務器本身還大:

  • 解析结果在不同地区不一致,蜘蛛從某個节点解析到的 IP 恰好不可用
  • TTL 设得過短,解析請求频繁,缓存命中率低
  • 同一域名下有多條 A 记錄,其中一條指向已经下线的机器
  • 解析服務商本身出現抖動,導致間歇性超时

這類問题的特点是“时好时坏”,日誌里能看到一部分抓取成功、一部分直接连不上。

TLS 握手

HTTPS 站点在拿到頁面之前還要過證书這一關。常见的坑包括:

  • 證书到期没有及时續,蜘蛛直接被拦在门外
  • 證书鏈不完整,部分客戶端能過、部分過不了
  • 只支持較新的协议版本,老一点的抓取客戶端协商失敗
  • 多域名證书里漏了某個別名域名

這類問题往往表現為整站抓取骤降,而不是某几個頁面出問题。

首字节時間

服務器收到請求後多久吐出第一個字节,直接决定蜘蛛這一次抓取要占用多久的连接。首字节慢,常见原因有:

  • 後端查询没有合适索引,頁面每次都要現算
  • 缓存命中率低,大量請求穿透到資料库
  • 頁面依赖外部接口,接口一慢整頁就慢
  • 服務器负载高,請求在队列里排队等待處理

响應体传輸

首字节之後,响應体要完整传完才算一次成功抓取。连接被中途重置、响應体被截断、返回的長度声明和實际内容對不上,都會让蜘蛛拿到半截頁面。半截頁面里的連結自然也是残缺的,這會直接影响後續的 URL 發現。

怎么從現有資料里對照

不需要額外工具,几份現成的資料就能大致定位:

  1. 服務器訪問日誌:看蜘蛛請求的响應時間分布,不只看平均值,重点看尾部那部分慢請求
  2. 狀態碼分布:连接层失敗往往留下 499、502、504,或者干脆没有记錄
  3. 抓取統計里的主机狀態:搜尋引擎後台一般會给出主机可用性和平均响應時間
  4. 證书和 DNS 的到期時間:设個提醒,比出問题後再排查省事

能做的几件事

  • 保持解析稳定:TTL 設定在合理区間,多條 A 记錄要确保都能正常服務,切換 IP 时留出足够時間
  • 證书提前續期:把續期做成自動流程,別等到期当天
  • 压首字节:给蜘蛛常抓的頁面做好缓存,减少每次請求都現算的情况
  • 不要對蜘蛛做粗暴限流:如果担心压力,用明确的信号回應,比如返回 503 並带上 Retry-After,而不是直接丢弃连接
  • 监控尾部延迟:平均值好看不代表没問题,慢請求更容易打断抓取
抓取量下降时,先確認蜘蛛能不能正常拿到完整的响應,再去查内容和内鏈。顺序反了,容易在没問题的地方反复改。

归根结底,URL 發現和内容质量决定蜘蛛“愿意抓多少”,而這條從 DNS 到首字节的鏈路决定蜘蛛“能不能抓到”。两者都顺的时候,抓取量的變化才更接近内容层面的真實反馈。