站点运营

站点运营:缓存头与 Last-Modified,别让蜘蛛反复拉取没变的页面

很多站点的响应头里,Last-Modified 每次都在变,ETag 也不稳定,蜘蛛每次都要重新抓一遍完整正文。这篇从站点运营角度讲缓存头自查:拉两遍响应头做对比、带上 If-Modified-Since 看是否返回 304、检查 CDN 有没有改写头部,并给出静态资源与 HTML 的缓存设置原则和月度抽查节奏。

站点运营

站点运营:缓存头与 Last-Modified,别让蜘蛛反复拉取没变的页面

缓存头为什么会出现在运营视角里

蜘蛛每天能分配给一个站点的抓取次数是有限的,具体多少由它自己决定,我们看不到也改不了。但有一件事是可以做的:让它在已经确认没变化的页面上少花一点时间。如果每个页面每次被抓都返回 200 和完整正文,服务器要重新拼一次页面,蜘蛛也要重新解析一遍;如果服务器能明确告诉它“这个页面自上次之后没改过”,它就有机会直接跳过内容抓取。

这个信号主要来自响应头里的几项:Last-ModifiedETagCache-ControlExpires。它们本来是给浏览器和 CDN 用的,但蜘蛛同样会读。

三个常见的错误配置

1. Last-Modified 每次都变

有些 CMS 或者模板在输出头的时候,顺手写了当前时间。结果就是:不管页面有没有改,每次响应的 Last-Modified 都是新的,蜘蛛永远得不到“未修改”这个判断依据,304 也就无从谈起。

2. ETag 不稳定

ETag 如果基于文件 inode、进程 ID 或者随机串生成,多台服务器之间就会互相打架。蜘蛛上一次从 A 机器拿到一个 ETag,这一次从 B 机器拿到另一个,它只能当成新内容处理。

3. 全局关掉了缓存

有的站点为了“保证内容最新”,在 Nginx 或应用层给整站加了 no-store、no-cache、max-age=0,静态资源、栏目页、文章页一视同仁。对用户来说影响不大,对抓取来说就是每一次都按全新页面处理。

怎么自查

  • 用 curl -I 或者浏览器开发者工具,拉两遍同一个 URL 的响应头,比较 Last-ModifiedETag 有没有变化。
  • 如果页面确实没有改动,两次的值应该完全一致。
  • 带上 If-Modified-Since 再请求一次,看服务器会不会返回 304。
  • 顺手看一下 Cache-Control 有没有作用到 HTML 上,图片、CSS、JS 这些静态资源是不是配了更长的缓存时间。
  • 经过 CDN 或反向代理的站点,两边都查一遍,确认缓存层没有把上游的头丢掉或者改写。

设置时的几个原则

  • Last-Modified 用内容本身的更新时间,也就是文章最后修改的时间,不要用当前时间。
  • 静态资源可以给长缓存,文件名带版本号或哈希值,更新时换名字,不用靠短缓存来兜底。
  • HTML 页面谨慎使用长缓存,可以用较短的 max-age 配合 Last-Modified 或 ETag。
  • 多机部署时统一 ETag 生成规则,避免同一页面在不同机器上给出不同标识。
  • 缓存头不是排名手段,它只影响服务器和蜘蛛之间的沟通效率。

观察节奏

不需要天天盯着。比较合适的做法是每个月抽一批代表性 URL——首页、栏目页、最近的几篇文章、几张图片——走一遍上面的检查。改动过服务器配置、上了 CDN、换过模板之后,再补做一次。

如果抓取日志里能看到大量重复请求同一批没变的页面,而且这些页面的响应体都是完整正文,那基本可以判断缓存头没有生效,值得回头看一眼。

缓存头不会让蜘蛛多来,也不会让收录变快。它只是在蜘蛛来的时候,让它少做一点重复劳动。这件事的价值不在某一次抓取,而在于把省下来的配额留给真正有变化、还没被发现的页面。