搜尋抓取

蜘蛛第二次来訪:Last-Modified、ETag 與 304 的取舍

蜘蛛對抓過的 URL 會重复回訪,並带上 If-Modified-Since 或 If-None-Match。本文說明 Last-Modified 與 ETag 的常见寫法問题,以及 304 用错时怎样让蜘蛛誤判内容已更新或未更新,並附一份可落地的检查清單。

搜尋抓取

蜘蛛第二次来訪:Last-Modified、ETag 與 304 的取舍

一個 URL 被蜘蛛抓過一次之後,並不代表它不會再被訪問。相反,只要頁面還在站内、還有内鏈指向它,蜘蛛就會隔一段時間再来一次。問题在于:第二次、第十次来訪时,服務器该怎么回答,才不會让蜘蛛白跑一趟,也不會让它誤以為内容没有變化。

蜘蛛為什么带着條件請求再来

第一次抓取时,服務器返回 200 和完整 HTML,通常還會带上 Last-Modified 與 ETag 两個响應头。之後蜘蛛再訪問同一個 URL 时,往往會把這两個值分別放進 If-Modified-Since 和 If-None-Match 請求头里,相当于問一句:我手上這份還有效吗?

如果服務器判断内容没變,可以回 304 Not Modified,不带正文。蜘蛛就知道该用手上的舊版本,省下的是带宽,也是它有限的抓取時間。判断不准,就會出現两種浪費:该回 304 却每次都回 200 全文,或者内容明明變了却回 304。

Last-Modified:精度和来源都要真實

Last-Modified 表示這個资源最後一次變化的时刻。它最常见的問题不是格式,而是来源不對:

  • 每次請求都輸出目前時間,等于告诉蜘蛛“這個頁面随时在變”,條件請求永遠不成立。
  • 時間取的是資料库寫入時間,而頁面正文来自另一張表,正文改了時間却没動。
  • 多台後端机器上的静態文件時間戳不一致,同一 URL 在不同机器上给出不同答案。
  • 時間格式或时区寫错,蜘蛛無法解析,只能当作普通响應處理。

更稳的做法是让 Last-Modified 跟着内容本身走:正文、模板中真正影响展示的字段變化时才更新。列表頁、聚合頁如果包含時間戳、随机推荐位,最好避開把這類内容算進最後修改時間。

ETag:稳定比“聪明”更重要

ETag 可以理解為内容指纹。理想狀態是:同一版本的内容算出同一個值,内容一變值就變。實际部署里,問题往往出在這几處:

  • ETag 里混入了随机數、目前時間或進程 ID,每次請求都不同。
  • 几台服務器各算各的,同样的内容得到不同的 ETag,蜘蛛在机器之間来回被“骗”。
  • 後台儲存了一次但内容没實际變化,ETag 變了,蜘蛛只能重下一遍。
  • 弱 ETag 與强 ETag 混用,语义不一致,判断容易出错。

不需要追求复杂的算法。用文件大小加修改時間,或者對正文做一次稳定哈希,只要在整個集群里保持一致,就比“看起来很聪明”的方案可靠。

304 用错,代價是蜘蛛记错版本

304 的含义很具体:和我上次拿到的那份一样。如果内容已经改了却仍然返回 304,蜘蛛會繼續沿用舊版本,頁面上的新段落、新價格、新标题可能迟迟不進入它的判断。反過来,本该回 304 的静態资源却總回 200,會让抓取预算消耗在重复下载上,图片、CSS、JS 這類文件尤其明顯。

304 不是一個省流量的開關,而是對“内容是否變化”這件事的承诺。承诺错了,比不回 304 更麻烦。

另外要注意,304 响應本身不應该再带正文,也不應该借 304 去传递错誤或跳轉信息。蜘蛛只看狀態碼和头部,多余的東西不會帮上忙。

中間有缓存层时,更容易出問题

CDN、反向代理、Nginx 缓存都可能參與條件請求的判断。需要確認几件事:請求头是否原样透传到源站;304 是否由缓存正确返回且不带响應体;缓存键是否會因為 Cookie、UA 不同而把同一 URL 拆成多份,導致命中率低、回源频繁。

和其他信号保持一致

Sitemap 里的 lastmod 與响應头的 Last-Modified 如果長期互相矛盾,蜘蛛會倾向保守判断,回訪节奏可能變得不規律。頁面如果确實更新了,除了改内容,也值得让時間信号同步更新,而不是靠一次次 200 全文去“提醒”它。

一份可落地的检查清單

  1. 用带條件請求头的請求測試几個典型 URL,观察返回碼和头部是否合理。
  2. 對同一個動態頁面连續請求两次,對比 ETag 與 Last-Modified 是否稳定。
  3. 抽查多台後端机器,確認同一 URL 给出同一组缓存驗證值。
  4. 真正修改一次内容,確認 ETag 或 Last-Modified 确實發生變化。
  5. 检查 CDN 與代理层,確認條件請求头被透传、304 被正确返回。
  6. 翻一段時間的訪問日誌,看看 304 與 200 的比例是否偏离预期。

這些配置不會直接带来收錄或排名,但能减少蜘蛛在“重复確認同一件事”上花掉的時間。把狀態碼和缓存驗證做對,是让抓取路径更顺的一小步,也是常被忽略的一步。