搜尋抓取

搜尋蜘蛛抓取:條件請求與 304 校驗異常造成的重复抓取梳理

條件請求是搜尋蜘蛛节省抓取预算的重要机制:携带 If-Modified-Since 或 If-None-Match 訪問时,服務器返回 304 即可跳過正文下载。但 ETag 频繁變化、Last-Modified 失真、CDN 改寫响應头或代理剥离條件头,都會让 304 失效,造成蜘蛛反复全量抓取。本文梳理常见異常表現與從日誌到回源头的排查顺序。

搜尋抓取

搜尋蜘蛛抓取:條件請求與 304 校驗異常造成的重复抓取梳理

條件請求在抓取流程中的位置

搜尋蜘蛛訪問一個已抓過的 URL 时,通常會带上 If-Modified-SinceIf-None-Match 請求头。服務器如果判断内容没有變化,返回 304 Not Modified,蜘蛛就不再下载正文,只更新一下抓取记錄。這個机制的作用很直接:减少传輸量,把有限的抓取预算留给新頁面和确有更新的頁面。

問题在于,304 的命中依赖两個响應头:Last-ModifiedETag。只要其中一個被错誤地生成、被中間层改寫,或者條件請求头根本没传到源站,蜘蛛就會一直在“全量下载”和“偶尔命中”之間反复,抓取效率明顯下降。

常见異常類型

ETag 每次都變

有些框架預設用 inode、進程 ID、時間戳拼接 ETag,同一份内容在两次請求里會拿到两個不同的值。蜘蛛下次带着舊 ETag 来對不上,只能重新拉全文。這類問题在動態渲染、多實例部署、负载均衡後的站点上特別常见。

Last-Modified 失真

  • 每次請求都刷新為目前時間,等于告诉蜘蛛“内容刚刚變了”。
  • 時間字段早于實际修改時間,導致蜘蛛認為頁面長期未更新。
  • 時間戳使用未来時間,部分客戶端會直接忽略该头。
  • 内容更新後没有同步修改時間,304 繼續命中,蜘蛛看不到新内容。

CDN 與源站的头不一致

邊缘节点開啟压缩、内容改寫或图片處理时,可能重新生成 ETag。结果是源站 ETag 與邊缘 ETag 對不上,蜘蛛從不同线路訪問得到不同校驗值,304 命中率被拉低。回源請求头被剥离的情况也存在,源站實际上一直返回 200,條件請求等于没有生效。

304 與 200 交替出現

部分站点在同一 URL 上时而返回 304、时而返回 200 並附带正文,且两次内容並不一致。這通常和缓存策略、灰度發布、多机房資料不同步有關。對蜘蛛来说,這會增加判断成本,也容易造成重复抓取。

排查顺序

  1. 先看抓取日誌中 304 的占比。如果長期接近零,說明條件請求基本没有生效。
  2. 用同一 URL 连續請求两次,记錄两次的 ETagLast-Modified 是否稳定。注意要分別從源站地址和對外域名各测一次。
  3. 手動带上舊的 If-None-Match、If-Modified-Since 發起請求,观察是返回 304,還是被忽略後直接返回 200。
  4. 检查 CDN 回源配置:是否改寫响應头、是否剥离條件請求头、是否對 HTML 做了額外處理。
  5. 检查應用层缓存開關。不少 CMS 或框架對登入態、動態參數頁面預設關閉缓存,這類頁面自然拿不到 304。
  6. 核對内容更新流程:編輯發布之後,Last-Modified 是否随内容真正發生變化。

配置建议

  • ETag 建议基于内容哈希生成,同一内容稳定輸出同一個值。
  • Last-Modified 與内容實际變動時間保持一致,不要伪造時間。
  • HTML 與静態资源分開配置缓存策略,不要共用一套規則。
  • CDN 回源时保留條件請求头,邊缘 ETag 與源站 ETag 不要随意重寫。
  • 多机房、多實例站点確認内容版本同步,减少 304 與 200 交替。
304 命中率高不代表内容會被更新收錄,它只說明這一次没有重复传輸。内容是否進入索引,仍取决于頁面本身的质量和抓取後的處理。

條件請求是抓取效率里比較容易被忽略的一环。把它和抓取日誌、CDN 回源配置放在一起核對,通常能發現一部分“蜘蛛反复来、頁面却没變化”的抓取浪費。