蜘蛛池知识

蜘蛛池入口頁的缓存协商:Last-Modified 與 ETag 该不该给蜘蛛用

蜘蛛回訪入口頁时不會直接下载整頁,而是先做一次缓存协商。本文讲清 Last-Modified、ETag、Cache-Control 各自的作用,304 狀態碼對蜘蛛池的實际影响,以及時間戳不更新、動態 ETag 這類常见坑,並给出几條可落地的配置建议。

蜘蛛池知识

蜘蛛池入口頁的缓存协商:Last-Modified 與 ETag 该不该给蜘蛛用

入口頁放上去之後,蜘蛛不會只看一次。第二次、第三次来的时候,它通常並不想重新下载整頁 HTML,而是先發一個带條件的請求,問服務器:這個 URL 從我上次拿到的版本到現在,有没有變過。服務器如果回答「没變」,蜘蛛就只拿一個 304 狀態碼走人。這個過程就是缓存协商,靠的主要是 Last-Modified 和 ETag 两個响應头。

三個头各自管什么

  • Last-Modified:頁面最後一次修改的時間。蜘蛛下次請求會带上 If-Modified-Since,服務器比對時間,没變就返回 304。
  • ETag:内容的指纹,常见做法是文件修改時間加大小,或者内容哈希。蜘蛛带 If-None-Match 回来比對。
  • Cache-Control / Expires:管的是浏览器和 CDN 的缓存时長,對蜘蛛本身没有强制约束,但會影响 CDN 是否回源,間接影响蜘蛛看到的内容新舊。

304 對蜘蛛池意味着什么

蜘蛛池的入口頁通常數量多、單頁内容薄。如果每一頁每次被抓都完整回传一遍 HTML,出口带宽和响應時間都會被吃掉。返回 304 的好處很直接:传輸量小、响應快,蜘蛛能在同样的時間预算里多走几個 URL。但這不等于「304 越多越好」。

如果入口頁的内容确實變了,却因為 Last-Modified 没更新而返回 304,蜘蛛會繼續認為這一頁還是老样子,新加的内鏈、新換的标题都不會被重新讀取。對做 URL 發現的池子来说,這種情况比多花一点带宽更麻烦。

缓存头的作用是让蜘蛛少做無用功,不是让蜘蛛看不到變化。

几個常见誤区

  1. 動態生成 ETag。有些程序用進程 ID 或請求時間戳拼 ETag,同一份内容每次請求指纹都不同,蜘蛛每次都判定為「變了」,协商形同虚设,反而比不做更費资源。
  2. Last-Modified 寫成目前時間。為了顯得更新频繁,每次請求都返回 now(),结果是每次都全量回传,還把頁面真實的修改時間抹掉了。
  3. 只改内容不改時間。用模板批量插入内鏈或調整版式时,忘了更新文件時間或清缓存,Last-Modified 停在几周前,蜘蛛回来拿到 304,改動等于白做。
  4. 把 Cache-Control 设得很長,又指望蜘蛛快点看到新内容。這两個設定服務的是不同對象,CDN 缓存長不代表蜘蛛會慢,但可能造成回源内容和缓存内容不一致。

配置上的几点建议

  1. 静態 HTML 入口頁交给 Web 服務器自動處理 Last-Modified 和 ETag,不要手動覆盖。
  2. 動態生成的入口頁,用内容哈希算 ETag,或者干脆只给 Last-Modified,保證同一份内容的指纹稳定。
  3. 内容有實质變化时同步更新時間戳;只改了空白或注释,不必强行刷新。
  4. 用訪問日誌观察 304 與 200 的比例。全是 200 說明协商没生效;全是 304 而内容明明更新過,說明時間戳维護有問题。
  5. 不要把缓存协商当成提升抓取量的手段。它省的是重复传輸,並不改變蜘蛛愿不愿意来。

最後提醒一句:缓存头解决的是「同一份内容別重复传」的問题,它跟内容质量、URL 结构、站内路径设計是几件不同的事。把它做對,只是让蜘蛛在入口頁上少浪費一点時間;真正决定蜘蛛愿意走多遠的,還是那些頁面上有没有值得繼續爬的東西。