蜘蛛池知识

蜘蛛池入口页的缓存策略: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. 不要指望用缓存去左右蜘蛛的访问频次,它只影响抓到什么,不影响来不来。
缓存策略解决的是蜘蛛来时看到什么,不是蜘蛛会不会来。把它当成减少无效抓取的工具,而不是提升抓取量的手段。

对蜘蛛池来说,入口页的价值在于被稳定地发现和读取。合理的缓存设置能减少服务器的重复开销,也能避免蜘蛛反复拿到同一份旧内容;但如果指望靠调整缓存头去换取更多抓取频次,方向就偏了。先把手上的页面更新节奏理清楚,再决定缓存时间,比照搬某个参数值更实际。