蜘蛛池知识

蜘蛛池入口頁的缓存策略:Cache-Control 與 Last-Modified 该怎么设

入口頁被蜘蛛抓過之後,下一次拿到的是新版本還是本地舊副本,往往由响應头里的缓存指令决定。本文拆解强缓存、不缓存與带校驗缓存三種组合的差別,說明 ETag、Last-Modified 和 304 该怎么配合,以及 CDN 覆盖源站設定等常见問题。

蜘蛛池知识

蜘蛛池入口頁的缓存策略:Cache-Control 與 Last-Modified 该怎么设

入口頁被蜘蛛抓過一次之後,下一次什么时候来、来的时候抓到的是新版本還是缓存里的舊版本,很大程度上由响應头里的缓存指令决定。缓存設定本身不會让蜘蛛多来,但它會直接影响蜘蛛每次訪問时看到什么,進而影响它判断這個頁面值不值得再来。

缓存头對蜘蛛的實际影响

搜尋引擎的抓取程序在多數情况下會遵循 HTTP 缓存语义。如果入口頁返回 Cache-Control: max-age 一個很長的值,抓取端可能在這段時間内复用本地副本,即使服務器上的内容已经換過。反過来,如果完全禁用缓存,蜘蛛每次来都拿完整頁面,對服務器和带宽的压力會明顯上升,但内容更新能第一時間被感知。

關键在于:入口頁通常承担發現連結的功能,而不是承载需要實时更新的内容。這個定位决定了缓存策略應该偏保守,而不是偏激進。

几種常见的缓存组合

完全不缓存

返回 no-store 或 no-cache,每次請求都重新生成頁面。适合入口頁連結會频繁調整、需要快速反映變化的场景。代價是带宽和服務器 CPU 消耗高,入口頁數量一大就很容易把资源吃满。

長時間强缓存

設定 max-age 几天甚至更久。抓取端可能長時間使用舊副本,新加的連結要等缓存過期才可能被發現。對蜘蛛池這種以持續被發現為目的的结构来说,這個策略通常不合适。

带校驗的折中方案

設定一個較短的最大缓存時間,比如几分钟到一小时,同时返回 ETag 或 Last-Modified。抓取端下次可以带上 If-None-Match 或 If-Modified-Since 来問一句變了没,没變就返回 304,變了就返回新内容。這是体积和时效之間比較平衡的做法。

Last-Modified 與 304 的配合

很多批量生成的入口頁,頁面内容其實没有變化,但程序每次請求都重新拼一遍 HTML 並返回 200,這在抓取端看来就是内容一直變,容易造成重复抓取。正确做法是:内容没變就返回 304,並且不要在每次响應里刷新 Last-Modified 的值。如果時間戳每次都變,等于告诉蜘蛛頁面一直在更新,反而會招来更多無意义的回訪。

容易踩的几個坑

  • 缓存头和實际内容不一致:声明缓存一天,但頁面上挂着按小时轮換的連結,抓到的永遠是過期版本。
  • CDN 缓存覆盖源站設定:源站寫了 no-cache,CDN 层按預設規則缓存了,蜘蛛看到的是 CDN 的副本。
  • 全部入口頁共用同一個 ETag:可能導致部分頁面被誤判為未修改,新連結迟迟不出現。
  • 為了省流量把所有頁面设成長缓存:短期带宽資料好看了,長期發現效率下降。

落地时的几点建议

  1. 先明确入口頁的更新频率:如果連結列表一周才動一次,短缓存加校驗就够了;如果每天批量替換,缓存時間要压到分钟級。
  2. 统一在源站配置缓存策略,再检查 CDN 和反向代理有没有把設定改掉,用 curl -I 查看最终返回的响應头。
  3. ETag 要能反映真實内容差异,用内容哈希而不是生成時間。
  4. 把 304 的比例纳入监控:比例過低說明校驗没起作用,比例長期接近 100% 則要確認頁面是否真的没更新。
  5. 不要指望用缓存去左右蜘蛛的訪問频次,它只影响抓到什么,不影响来不来。
缓存策略解决的是蜘蛛来时看到什么,不是蜘蛛會不會来。把它当成减少無效抓取的工具,而不是提升抓取量的手段。

對蜘蛛池来说,入口頁的價值在于被稳定地發現和讀取。合理的缓存設定能减少服務器的重复開销,也能避免蜘蛛反复拿到同一份舊内容;但如果指望靠調整缓存头去換取更多抓取频次,方向就偏了。先把手上的頁面更新节奏理清楚,再决定缓存時間,比照搬某個參數值更實际。