蜘蛛池知识

蜘蛛池入口頁的缓存响應头:Last-Modified、ETag 與蜘蛛重复抓取的關系

蜘蛛重复訪問入口頁时,服務器返回的缓存相關响應头會直接影响它是否重新下载正文。本文說明 Last-Modified、ETag、Cache-Control 與 304 狀態碼在蜘蛛池入口頁上的實际作用,梳理多域名共用缓存、内容频繁改動时的處理思路,並给出几個可执行的自查步骤。

蜘蛛池知识

蜘蛛池入口頁的缓存响應头:Last-Modified、ETag 與蜘蛛重复抓取的關系

蜘蛛重复訪問同一個入口頁时,服務器並不總是把整頁内容重新發一遍。HTTP 协议里的條件請求机制,让蜘蛛可以先問一句“我上次拿到的那份還作數吗”,服務器用 304 回答“没變”,双方都省流量。這套机制原本是给浏览器设計的,但在蜘蛛池场景下,它同样在悄悄影响抓取节奏。

條件請求是怎么發生的

蜘蛛在第一次抓取入口頁後,會记錄响應头里的 Last-ModifiedETag。下次抓取时,它把這些值放進請求头的 If-Modified-Since 或 If-None-Match。服務器比對後返回两種结果:内容没變就返回 304,不带正文;變了就返回 200 加新正文。

對蜘蛛来说,304 不是坏事。它說明連結還活着、頁面结构稳定,只是内容没更新。真正需要担心的是另一種情况:内容明明改了,服務器却因為缓存配置错誤一直返回 304,蜘蛛就會長期停留在舊版本上。

Last-Modified 和 ETag 分別管什么

  • Last-Modified 基于文件修改時間,精度到秒。静態頁面、直接由文件系統吐出的入口頁用它最省事。缺点是文件被重新生成但内容一样时,時間戳變了,蜘蛛會重新下载一份完全相同的内容。
  • ETag 是内容的指纹,理论上更精确。但很多服務器預設用“inode + 修改時間 + 大小”生成 ETag,多台机器之間不互通,蜘蛛在负载均衡的站点上會看到 ETag 反复變化,结果每次都是 200 全量返回。

两者同时存在时,蜘蛛通常優先使用 ETag。如果 ETag 不稳定,不如直接關掉它,只留 Last-Modified。

Cache-Control 不是给蜘蛛看的,但蜘蛛會看

Cache-Control: max-age 主要约束浏览器和中間缓存。蜘蛛一般不完全遵守它,但如果設定成很長的 max-age 又配合 CDN,中間层可能把舊内容一直吐给蜘蛛。入口頁這類需要反映最新狀態的頁面,比較稳妥的做法是不给過長的缓存時間,或者让 CDN 對爬虫 User-Agent 回源。

缓存的目标是减少重复传輸,不是让蜘蛛看不到更新。這两件事经常被混為一谈。

入口頁内容频繁改動时怎么办

如果入口頁每隔几小时就換一次推荐位或時間戳,條件請求的意义就不大,蜘蛛几乎每次都會拿到 200。這種情况下更值得關注的是改動本身有没有價值:正文主体不變、只變頁脚年份,對蜘蛛来说等同于没變,反而浪費一次抓取。

真需要频繁更新的頁面,可以只更新局部内容並保持 Last-Modified 稳定,避免因為無意义的响應头抖動引發蜘蛛高频回訪。

几個常见誤区

  • 给所有响應套用固定 ETag 模板,導致大量頁面指纹雷同,蜘蛛判断混乱。
  • 反向代理和後端各自加一层缓存头,最终輸出的 Last-Modified 比實际内容還新。
  • 入口頁返回 304 却同时带了一段說明文字,正文長度和狀態碼不一致。
  • 為了让抓取日誌好看,人為让頁面永遠返回 200,抓取量上升了,重复内容比例也一起上升。

自查步骤

  1. 用 curl -I 连續請求两次入口頁,確認第二次返回的 Last-Modified 或 ETag 與第一次一致。
  2. 在請求头里带上 If-None-Match,確認服務器能正确返回 304。
  3. 改動頁面正文後再請求一次,確認返回 200 且 ETag 已更新。
  4. 換一台机器或換一個出口 IP 請求,检查 ETag 是否仍然相同。
  5. 對照抓取日誌,看蜘蛛對同一入口頁的狀態碼分布,判断是 200 偏多還是 304 偏多。

缓存配置属于那種平时不出問题、出問题就很难排查的环节。把入口頁的响應头保持稳定、可预测,比追求某種所谓的最優設定更實际。