蜘蛛抓取的时候,它请求的域名通常解析到 CDN 的边缘节点,而不是源站服务器。这带来一个常被忽略的事实:蜘蛛拿到的页面,未必是源站此刻生成的那一份,可能是节点上一次回源时缓存下来的副本。排查抓取异常时如果只盯着源站,很容易漏掉中间这一层。
蜘蛛的请求先落到哪里
一个请求大致会走这样的路径:DNS 解析到 CDN,节点先判断本地是否有可用的缓存副本。命中就直接返回,不再打扰源站;未命中则回源拉取,源站生成页面,节点再按规则决定是否缓存、缓存多久。对蜘蛛来说,两种情况返回的都是 200,从前端看不出区别,但内容的时效性和稳定性可能完全不同。
缓存命中时,蜘蛛看到的可能是旧版本
如果 HTML 的缓存时间设置得比较长,而页面内容更新频繁,节点在 TTL 内就会持续返回旧版本。蜘蛛可能在几小时内多次访问同一个 URL,一次命中缓存、一次回源,拿到两份不同的内容。这种不稳定未必会直接导致什么问题,但会让“更新了却没变化”的判断变得困难——更新没被看到,不一定等于蜘蛛没来。
比较稳妥的做法是让重要页面的缓存时间与更新频率匹配。栏目页、首页这类更新快的页面可以短一些;常年不变的详情页可以长一些。内容有实质性更新时,主动刷新对应 URL 的缓存,比等待 TTL 到期更可控。
按 UA 或按地区分流,会放大差异
部分站点会在 CDN 上按 UA 区分返回内容,比如给爬虫一份精简版、给浏览器一份完整版。这种做法在短期内看似节省资源,但它让蜘蛛抓到的页面与用户看到的页面出现分叉,长期看并不划算。
另一个容易出问题的地方是 Vary 头。如果把 Vary 设成包含 Cookie、语言、设备等过多维度,缓存会被切得很碎,甚至退化成几乎不缓存,回源压力上升。对需要被稳定抓取的 HTML 页面来说,Vary 维度越少越好。
地区化内容也值得留意。给不同地区返回不同版本时,蜘蛛从哪个节点访问、拿到哪一份,往往不受你控制。如果版本差异涉及主要正文,最好通过 URL 区分,而不是靠节点判断。
CDN 日志与源站日志各能说明什么
看抓取情况时,两边的日志都要看,但要知道各自的盲区。
- 源站日志只记录回源请求。如果节点大量命中缓存,源站会显得“蜘蛛来得少”,但这不代表抓取没有发生。
- CDN 日志记录到达边缘的请求,能看到抓取频次和 URL 分布,但通常看不到回源细节,也不一定区分命中与回源。
- 两边对照,才能判断抓取量下降是蜘蛛真的少来了,还是被节点消化掉了。
可以定期检查的几项
- 确认需要被抓取的 HTML 页面允许缓存,缓存时间与内容更新节奏对得上。
- 检查 Vary 头,去掉对抓取没有帮助的分化维度。
- 确认蜘蛛 UA 没有被单独处理成另一套内容。
- 检查 CDN 侧的限速与防护规则,避免正常抓取被误判成异常流量而返回 403 或 429。
- 确认回源失败时的兜底策略。如果回源异常时节点返回错误页,而错误页又被缓存下来,影响会持续一段时间。
- 定期比对 CDN 日志与源站日志中的抓取记录,确认请求链路没有断在中间层。
小结
CDN 不是抓取链路之外的旁观者,它本身就是链路的一部分。缓存策略、TTL、Vary 头、UA 处理规则,都会影响蜘蛛最终看到什么。把这些配置和日志纳入日常检查,很多“抓取异常”会变得更容易定位。
排查抓取问题时,先问一句:蜘蛛的请求到底落在了哪一层?答案不同,接下来要查的东西也完全不同。