常见問题

入口頁返回 304 Not Modified:搜尋蜘蛛還會重新解析里面的連結吗

不少站点给蜘蛛池入口頁加了缓存策略,服務器會對搜尋蜘蛛返回 304。有人担心這样一来爬虫就不再解析頁面里的連結。本文說明 304 的触發條件、已有連結和新連結分別受什么影响,以及缓存校驗信息寫错时该怎么排查。

常见問题

入口頁返回 304 Not Modified:搜尋蜘蛛還會重新解析里面的連結吗

给蜘蛛池入口頁做缓存優化时,常有人問:服務器對搜尋蜘蛛返回 304 Not Modified,爬虫是不是就不再看這個頁面了?入口頁里新增的目标連結,還能不能被發現?這個問题要拆成两件事看:爬虫手里有没有缓存副本,以及缓存校驗信息准不准。

先搞清楚 304 是谁触發的

304 不是服務器主動發的,而是爬虫带着校驗信息来問“頁面變了吗”,服務器回答“没變”。常见的校驗字段有两组:If-Modified-Since 對應 Last-Modified,If-None-Match 對應 ETag。爬虫只有在之前成功抓取並儲存了這些校驗信息的前提下,下一次請求才會带上它們。

所以還有一種情况是:爬虫從没抓過這個入口頁,手里没有缓存,請求里不會带校驗头,服務器也就無從返回 304,只能正常返回 200 和完整 HTML。

返回 304 时,爬虫手里的連結還在不在

爬虫收到 304,意味着它會沿用本地缓存的那份 HTML,不會重新下载正文。由此有两個结果:

  • 如果上一次抓取时那份 HTML 已经解析出了連結,這些連結早已進入待抓取队列,不會因為這次 304 被撤销。
  • 如果入口頁在這次改動中新增了連結,而服務器仍然回答“没變”,新連結就不會被發現,因為爬虫根本没看到新版 HTML。

也就是说,304 本身不會伤害已经發現的 URL,真正的問题在于缓存校驗信息與實际内容不一致。

哪几種情况容易出問题

Last-Modified 更新不及时

有些程序把 Last-Modified 寫成頁面首次生成時間,或者寫死成某個固定值。入口頁加了新連結,HTML 确實變了,但 Last-Modified 没動,爬虫一問,服務器還是回 304,新連結自然浮不出来。

CDN 或缓存层提前拦截

如果 CDN 把入口頁缓存住,並且對带校驗头的請求直接回 304,源站的新内容可能根本没有參與判断。這類問题通常表現為:本地直接訪問源站能看到新連結,走 CDN 域名却看不到。

連結靠脚本動態生成

如果入口頁的連結需要执行 JavaScript 才會插入 DOM,而爬虫基于缓存副本判断頁面未變化、跳過重新處理,新連結的發現會更慢。静態可讀的連結在這種场景下更稳妥。

長期只拿到 304,抓取频率被下調

多次返回 304 說明内容稳定,爬虫通常會降低對這個入口頁的抓取频次。這本身不是惩罚,但如果站点長期依赖這個入口頁發現新 URL,抓取节奏變慢會直接影响發現速度。

怎么排查和調整

  • 看服務器或 CDN 日誌里入口頁的 304 占比。如果長期接近 100%,而你确實在持續更新入口頁,先怀疑校驗信息不對。
  • 對比入口頁 HTML 的實际内容指纹與 Last-Modified、ETag 的生成逻辑,確認内容變化时校驗值一定會變化。
  • 確認 304 是源站返回的還是 CDN 返回的,逐层排查,不要只看一次浏览器開發者工具的结果。
  • 關注目标 URL 的首次發現時間有没有變慢,可以把日誌按天對比。

更實用的做法

入口頁不需要频繁變動,稳定通常是好事;關键是變了就让爬虫知道,没變就別制造變化。

  • 每次更新入口頁内容後,確認 Last-Modified 或 ETag 同步更新,不要手動寫死。
  • 不要為了催抓取频繁修改 Last-Modified、频繁全量返回 200,這會消耗抓取配額,也容易让爬虫判断頁面狀態不稳定。
  • 重要目标 URL 尽量多通道暴露:入口頁 HTML 里保留可讀的 a 标簽連結,再配合 sitemap 一起用。
  • 入口頁改動前後记錄新連結出現的大致時間,方便判断缓存策略有没有拖慢發現。
304 不是坏事,它說明缓存机制在工作。真正需要盯住的是缓存校驗信息是否如實反映了頁面内容的變化。

如果入口頁内容長期稳定、校驗信息准确,304 只减少了無效传輸,不會让已经存在的連結消失。發現變慢时,先查校驗逻辑和缓存层,而不是急着關掉缓存或者频繁改動頁面。