蜘蛛池入口页本身不复杂,通常就是一页挂着若干 URL,等搜索蜘蛛来取。但很多人在核对“日志里明明有抓取,链接却没更新”时,会漏掉中间那一层——缓存。日志里的 200,不代表蜘蛛拿到的是源站此刻生成的那份 HTML。
缓存可能出现在四个位置
- 浏览器与本地缓存:对蜘蛛影响相对小,因为爬虫通常不会长期复用本地缓存,但仍会参考 Cache-Control 等响应头。
- CDN 边缘节点:最常见的一层。节点命中后直接返回旧副本,源站甚至看不到这次请求,日志里自然也没有记录。
- 反向代理或网关缓存:Nginx、Varnish 之类,规则配错时会把带参数的 URL 全部当成同一个资源处理。
- 应用层缓存:页面片段、查询结果缓存,内容更新后需要等过期或主动清除才会生效。
按 UA 分流缓存最容易踩坑
有些站点为了让蜘蛛看到“干净版”页面,会按 User-Agent 返回不同内容,并给不同 UA 设置不同缓存键。问题在于:部分 CDN 默认不把 UA 计入缓存键,于是蜘蛛拿到的可能是给普通访客准备的版本;反过来,如果缓存键里带了 UA,而蜘蛛 UA 又存在多种变体,缓存命中率会掉得很低,源站压力立刻上升。
如果确实需要差异化返回,更稳妥的做法是把差异放在源站逻辑里,而不是靠缓存层判断 UA。缓存只负责同一份内容的高效分发,判断逻辑越简单越不容易出问题。
缓存给入口页带来的三种具体影响
链接更新了,蜘蛛拿到的还是旧的
入口页的主要作用是把新 URL 递出去。如果 CDN TTL 设成 24 小时,而你每小时更新一次链接列表,蜘蛛在大部分时间里看到的都是同一份旧 HTML。这不是蜘蛛不来抓,而是你递出去的还是上一批地址。
状态码也会被缓存
页面临时返回 5xx,或者测试阶段返回过 404,如果被缓存层记下来,后续一段时间蜘蛛访问得到的都是这个状态码。之前排查过的“蜘蛛掉头就走”,有相当一部分根因就在负缓存上。
同一路径出现多份内容
带参数的 URL 被规则归一化缓存后,不同参数可能返回同一个副本,蜘蛛会认为这些地址内容重复;反过来,如果缓存键包含随机参数或时间戳,同一逻辑页会生成无数份副本,抓取预算被白白消耗。
排查顺序建议
- 用蜘蛛 UA 直接请求入口页,对比返回内容与源站是否一致,重点看响应头里的 Age、X-Cache、CF-Cache-Status 一类字段。
- 对比服务器日志与 CDN 日志:源站日志里没有的请求,多半在边缘节点就被处理掉了。
- 检查缓存键规则,确认 URL 参数、Host、UA 是否被纳入。
- 确认 4xx、5xx 是否被缓存,以及对应的负缓存时长。
- 更新链接后主动刷新相关 URL,而不是等 TTL 自然过期。
配置上的几条建议
- 入口页这类需要频繁更新的页面,TTL 设短一些,几十分钟到几小时比较常见,具体看你的更新频率。
- 不要缓存 4xx 和 5xx,或把负缓存时间压到很短。
- 缓存键尽量只保留真正影响内容的维度,避免无意义参数和不稳定的 UA。
- 入口页 HTML 保持“可缓存但可快速刷新”,与图片、CSS 这类长缓存资源区分开。
- 每次调整缓存规则后留出观察窗口,用日志对比调整前后的抓取情况。
缓存不是敌人,它帮源站挡掉了大量重复请求。真正的问题在于:当入口页需要“新鲜”的时候,缓存还在按旧规则工作。
把缓存当成蜘蛛链路上的一个参与者来看,很多“蜘蛛抓不到新链接”的问题会变得好解释:不是蜘蛛不来,而是它每次来都被同一份旧副本挡在门外。定期核对缓存规则与更新节奏是否匹配,比事后翻日志猜测要省力得多。