搜尋抓取

重訪时的 304:條件請求與缓存头怎么影响蜘蛛判断

蜘蛛重訪頁面时並不總是重新下载整份 HTML,而是带上條件請求头。服務器返回 304 表示内容未變。本文說明 Last-Modified 與 ETag 的作用、凭證不稳定的几種常见情况、如何在訪問日誌里核對 304,以及它和 Sitemap lastmod 之間的關系。

搜尋抓取

重訪时的 304:條件請求與缓存头怎么影响蜘蛛判断

蜘蛛第一次抓完頁面後,後續重訪並不總是重新下载整份 HTML。如果服務器支持條件請求,蜘蛛會带上 If-Modified-Since 或 If-None-Match,服務器判断内容没變就回一個 304,告诉對方内容還是原来那份。理解這套机制,能解释很多日誌里看起来奇怪的現象。

條件請求的两種凭證

Last-Modified 與 If-Modified-Since 用時間做比較,粒度到秒;ETag 與 If-None-Match 用内容标识做比較,粒度更细。两者可以同时存在,服務器按自己的規則决定用哪個。對抓取来说,關键不是用哪一種,而是這個值要稳定:内容没變时,凭證也不能變。

常见的凭證不稳定

  • ETag 由進程 ID、時間戳或随机數生成,每次請求都不同,蜘蛛每次都被判定為新内容。
  • Last-Modified 取自動態生成時間,頁面内容没變但時間一直在跳。
  • 反向代理或 CDN 改寫了响應头,回源與邊缘的 ETag 不一致。
  • WAF 拦掉了 If-None-Match 請求头,服務器每次都返回 200 加完整正文。

這几種情况不會直接導致抓取失敗,但會让蜘蛛做很多無效下载,占用抓取額度,也可能让它誤判頁面的更新频率。

日誌里怎么確認

在訪問日誌中按狀態碼統計即可:304 的數量、對應的 URL,以及同一 URL 上 200 與 304 的交替情况。

  1. 挑一批内容基本不變的頁面,看它們重訪时是否稳定返回 304。
  2. 如果全是 200,先看响應头里的 ETag 是否每次都變,再看中間层有没有改寫。
  3. 如果 304 比例異常高但頁面其實已经改過,检查缓存层是否给出了過期的凭證。
304 表示内容没變,不表示没被抓。它同样是蜘蛛的一次有效訪問,只是没有传輸正文。

和 Sitemap 的 lastmod 配合

Sitemap 里的 lastmod 是给蜘蛛的另一種提示,和 HTTP 层的凭證本质上是同一件事的两種表達。如果 lastmod 寫着昨天更新,而服務器對同一 URL 一直回 304,两個信号就互相矛盾。更新内容後,让 lastmod、Last-Modified、ETag 三者一起變化,是最省事的做法。

几個值得注意的细节

  • 304 不传輸正文,蜘蛛拿到的是它缓存里的副本。如果副本已经過期而服務器仍回 304,更新可能被延迟感知。
  • 對频繁變動的頁面,比如列表頁和首頁,缓存头不宜設定過長,否則蜘蛛看到的一直是舊版本。
  • 對稳定不變的内容頁,允许 304 是好事,既省带宽,也能让蜘蛛把額度留给別的 URL。
  • 服務器不稳定时,條件請求可能返回 5xx 或超时,這时要按服務器問题排查,而不是当成缓存配置問题。

小结

把 304 理解成一次確認而不是一次抓取失敗,排查思路就清晰了:先確認凭證是否稳定,再確認中間层有没有改寫响應头,最後看 Sitemap 的 lastmod 和 HTTP 层是否说了同一件事。三處對齐,蜘蛛對頁面更新狀態的判断才不會来回摇摆。