很多站点在接入 CDN 或反向代理之后,会碰到一种情况:自己在浏览器里看到的页面是新的,日志里蜘蛛抓到的却是旧版本;或者普通用户访问正常,蜘蛛那一侧却频繁出现 403、超时和验证页面。问题往往不在页面本身,而在蜘蛛和你之间多出来的那一层缓存与防护。
蜘蛛抓到的和你看到的,可能不是同一份 HTML
CDN 的默认逻辑是就近返回缓存。节点上的副本有各自的 TTL,也有各自的淘汰策略,不同节点、不同地区的缓存状态并不一致。蜘蛛从不同 IP 段发起抓取,命中的可能是 A 节点的新副本,也可能是 B 节点的旧副本。如果页面刚更新、缓存又没过期,蜘蛛就拿不到新内容,抓到的链接和文本都停留在上一版。
更麻烦的是缓存分裂:有些配置会按 UA、Cookie、查询参数生成不同的缓存键。蜘蛛没有 Cookie、UA 相对固定,命中的缓存桶和普通用户不同,于是出现用户能看到的内容、蜘蛛看不到的情况,而日志里状态码还是 200,从表面上完全看不出异常。
缓存命中率会影响抓取节奏
缓存命中时响应通常在几十毫秒,回源慢时可能几百毫秒甚至超时。蜘蛛在单位时间内的抓取量,和服务器响应速度直接相关:同样的时间窗口里,响应快,翻过的 URL 就多;响应慢、频繁超时,抓取频次会相应被压下来。这属于正常结果,不是针对某个站点的惩罚,但会实实在在拖慢新页面的发现速度。
所以缓存层对抓取的影响有两面。命中率高、回源稳定,等于给蜘蛛让出了更多抓取空间;缓存穿透严重、回源抖动,抓取效率和稳定性都会打折。
三个常见问题
一、缓存返回旧版本
- 内容更新后没有主动刷新缓存,蜘蛛短期内反复抓到旧 HTML。
- 缓存 TTL 过长,新链接在旧副本里根本不存在,蜘蛛自然发现不了。
- 不同节点 TTL 不一致,蜘蛛在不同时间看到的内容对不上。
二、防护层拦住了蜘蛛
有些 WAF 或安全策略默认只放行浏览器特征明显的请求,对陌生 UA 直接返回 403、人机验证页或跳转。蜘蛛拿到的就是这类响应,页面正文一个字都读不到。表现是:日志里蜘蛛请求不少,但状态码集中在 403、429、503,抓取覆盖始终上不去。
三、状态码在传递中被改写
源站返回 404 或 301,经过缓存层后有时被替换成 200 加一个空页面或错误提示页。蜘蛛看到 200,就把这个 URL 当作正常页面处理;下次再来还是同一份空内容,反复几次之后,这个 URL 在抓取里就变成了低价值目标。这类问题排查成本不低,但影响很直接。
怎么排查
- 在服务器和 CDN 两侧各看一遍日志,重点比对蜘蛛 UA 的状态码、响应时间和回源比例。
- 用同一个 URL 分别以普通访问和蜘蛛特征请求,比较返回的 HTML 是否一致。
- 检查缓存规则里是否按 UA、Cookie、参数分桶,确认蜘蛛命中的是哪一版。
- 检查防护策略的白名单,确认主流搜索蜘蛛的 IP 段和 UA 都被放行。
- 确认回源时状态码没有被改写,404 就返回 404,301 就返回 301。
几个务实的处理方式
- 内容更新后主动刷新相关 URL 的缓存,不要等 TTL 自然过期。
- 给搜索蜘蛛配置独立的回源或缓存策略,保证它们拿到的是最新、完整的 HTML。
- 在防护层放行验证过的蜘蛛 IP 段,避免用验证页回应抓取请求。
- 控制缓存键的维度,能不分 UA 就不分,减少同一 URL 的缓存副本数量。
- 把响应时间当作抓取指标来监控,回源慢的问题尽早处理。
缓存层的作用是让访问更快,不是改变蜘蛛能看到什么。把版本一致、状态码一致、放行规则这三件事确认好,蜘蛛那边的抓取才不会莫名其妙地卡住。
蜘蛛并不需要特殊照顾,它需要的是稳定和一致:稳定指响应速度和可用性,一致指不同节点、不同时间返回的内容是同一份。把这两点做到位,抓取覆盖和发现效率的变化通常会自己显现出来。