爬虫每次来访,都会先问一次“这个页面变了没有”。服务器怎么回答,决定了它是重新下载一遍整页,还是收下一句“没变”就走。对蜘蛛池来说,这个细节直接关系到抓取效率:入口页本身内容不多,却反复占掉抓取预算,目标页就少了一次机会。
缓存头在爬虫眼里是什么
HTTP 缓存机制本来是为浏览器和 CDN 设计的,搜索引擎爬虫同样遵守这套规则。它手里存着上次抓到的副本和对应的验证信息,下一次请求时把这些信息带回来,服务器据此判断要不要重新发一遍正文。
- Cache-Control:告诉爬虫和中间层可以缓存多久。max-age 越长,爬虫越倾向于先不重新抓。
- ETag:页面内容的指纹,用来做验证式缓存。
- Last-Modified:页面的最后修改时间。
- 304 Not Modified:验证结果是没变,只回响应头,不回正文。
304 是省流量,还是被当成“没变化”
304 对爬虫是友好信号,说明页面没动,它不必重算内容,这次抓取的成本也很低。但有两件事要注意:一是入口页如果长期只回 304,它在你池子里的活跃度信号会趋于静止;二是有些自建服务把 304 回得含糊,比如正文其实换了但 ETag 没跟着更新,爬虫就会一直抱着旧副本的内容结构。
更常见的坑是反过来:动态生成的入口页每次请求都返回不同的 ETag 或 Last-Modified,爬虫每次都被判为“已更新”,于是每次都拉全文。这类页面在池子里数量一多,抓取预算被吃掉得很快,真正需要被发现的链接反而排在后面。
不同类型的入口页怎么配
静态模板页
内容基本不变,可以给较长的缓存时间,同时保持 ETag 稳定,让爬虫多数时候只做一次验证请求。改动模板时记得让 ETag 跟着变,否则爬虫看不到这次更新。
动态生成的枢纽页
这类页面的作用是承载并输出目标链接,链接结构可能随时调整,更适合用较短的缓存时间,或者用 no-cache 加验证式缓存,保证爬虫每次都能拿到当前版本。
带跳转或中间层的页面
缓存头尽量和跳转方式保持一致。如果响应头说可以缓存很久,而跳转目标随时会改,爬虫和中间层就会各自拿着不同版本,之后排查问题会非常费劲。
配置时容易踩的几个坑
- 用随机数当 ETag:等于每次都告诉爬虫“内容变了”。
- Last-Modified 直接用当前时间:每次请求的时间都不同,同样造成“永远在更新”的错觉。
- CDN 覆盖源站缓存头:源站改了没生效,或者反过来把不该长缓存的内容缓存了很久。
- 对 404、410 也返回长缓存:页面已经撤掉,缓存里还挂着一份旧响应。
- 忽略 Vary:同一个 URL 按 UA 返回不同内容时,缓存可能串味,爬虫拿到的是给别人看的那一份。
几个可以照着做的建议
- 先固定住 ETag 的生成规则,用内容哈希,不要用时间戳或随机值。
- 内容没变就不要动 Last-Modified,改了内容再让它变化。
- 动态入口页优先考虑短缓存加验证式缓存,而不是一味拉长 max-age。
- 定期抽查响应头,用命令行工具直接看源站和 CDN 各返回了什么,确认没有被改写。
- 把缓存头的设置和页面的更新节奏对齐,改版时同步调整,别让两边各说各话。
缓存头不是排名开关,它只是让爬虫少做无用功。省下来的预算能不能用在目标页上,还要看链接结构和内容本身是否站得住。
小结
蜘蛛池入口页的价值在于把爬虫顺利送到目标页,而不是自己反复被完整抓取。把 ETag、Last-Modified 和 Cache-Control 配得稳定、可预期,爬虫就能少花力气在验证上;反之,一个随机 ETag 就足以让整池页面的抓取效率打折扣。配置完成后,建议结合访问日志看一段时间的抓取次数和响应码分布,再决定是收紧还是放宽缓存策略。