搜索抓取

CDN 缓存与抓取:蜘蛛每次拿到的是哪一份 HTML

蜘蛛的请求通常先到 CDN 或反向代理,命中缓存就直接返回,不一定回源。缓存键、Vary 头、边缘机器人规则、地域跳转和缓存过期策略,都会影响蜘蛛最终拿到的页面版本。本文梳理这一层常见的几处变量,并给出一份可执行的自查清单。

搜索抓取

CDN 缓存与抓取:蜘蛛每次拿到的是哪一份 HTML

做抓取分析时,很多人只看源站日志,忽略了中间那一层。实际线上,蜘蛛的请求往往先到 CDN 或反向代理,命中缓存就直接返回,不一定回源。于是“蜘蛛抓到了什么”取决于边缘节点怎么配置缓存键、怎么识别爬虫、怎么处理地域与实验分流。这几处任何一个设置不当,都可能在源站日志里留下一串 200,但蜘蛛拿到的页面跟用户看到的并不一样。

蜘蛛的一次请求会经过哪几层

  • DNS 解析:站点域名 CNAME 指向 CDN,蜘蛛拿到的是边缘节点 IP,不是源站 IP。
  • 边缘节点:判断缓存是否命中,命中则直接返回,未命中才回源。
  • 回源链路:源站返回 HTML,边缘按规则决定缓存多久、缓存成什么键。
  • 响应返回:状态码、响应头和 HTML 一起回给蜘蛛。

这四层里,通常只有第三层是你平时调试时打开的那台机器。

缓存键与 Vary:同一个 URL 可能存着几份 HTML

缓存键一般由 URL 加若干请求头组成。如果边缘把 User-Agent 算进缓存键(常见于配置了 Vary: User-Agent 的场景),搜索蜘蛛的 UA 和普通浏览器 UA 就会命中两个不同的缓存对象。这本身不算错,问题在于两份缓存可能来自不同时间的回源,蜘蛛拿到的那份可能比用户看到的更旧。

移动与桌面两套模板时更麻烦。如果边缘按 UA 分流模板,而蜘蛛的移动版 UA 又被误判成桌面,回源就会走错分支。

  • 尽量让同一 URL 在不同 UA 下返回同一份 HTML,渲染差异交给 CSS 或前端处理。
  • 确需按 UA 分流时,把已知搜索蜘蛛单独列一组规则,明确它走哪套模板。
  • 检查缓存键是否混入了 Cookie、语言、设备等变量,避免缓存被切成大量碎片,命中率骤降。

边缘上的机器人规则:别无声地把蜘蛛拦掉

不少 CDN 与安全产品默认开启机器人防护、速率限制或 JS 挑战。对普通爬虫这是好事,但搜索蜘蛛可能被一起拦下。表现通常是 403、429,或者一个需要执行 JS 的挑战页。蜘蛛拿到挑战页,这条 URL 这次抓取基本白跑。

验证方法不复杂:用 curl 带上搜索蜘蛛 UA 请求首页、列表页、详情页各几条,看返回的是真实 HTML 还是拦截页,再和普通 UA 的返回做对比。

规则上可以做分层:放行已知搜索蜘蛛(最好通过反向解析确认不是伪造 UA),对匿名高频请求做限速,而不是一刀切。

地域重定向与 A/B 测试

有些站点在边缘按 IP 国家或 Cookie 做跳转,把访客送到对应语言版本。如果蜘蛛从某个区域节点访问,可能被跳到语言站 A;换一个节点,又跳到语言站 B。结果同一批 URL 在蜘蛛那里反复换地址,抓取路径变得不稳定。

A/B 测试同理。边缘把一部分用户分流到 B 版本,如果蜘蛛也被分进去,它看到的页面和多数用户不同,内容判断容易出偏差。一般做法是对搜索蜘蛛固定走主版本。

缓存过期与条件请求

边缘缓存到期后,回源会带上 If-Modified-Since 或 If-None-Match。源站正常返回 304 时,边缘可以继续用旧副本,蜘蛛也省一次传输。但如果源站每次都对蜘蛛返回 200 全量 HTML,或者边缘把 304 改写成 200 加空 body,抓取开销就会被放大。

  • 确认源站的 Last-Modified、ETag 能透传到边缘这一层。
  • 确认边缘不会把 304 变成 200。
  • 页面内容确实变了再改时间戳,不要为了催抓取而频繁改动。

一份可以照着做的自查清单

  1. 用搜索蜘蛛 UA 请求几个代表性 URL,记录状态码与响应头。
  2. 看响应头里有没有缓存命中标记,例如各类 x-cache、age 字段。
  3. 绕过 CDN 直连源站请求同样 URL,对比 HTML 是否有差异。
  4. 在 CDN 后台查机器人报告,确认被拦截的请求里有没有搜索蜘蛛。
  5. 在源站日志里按蜘蛛 UA 统计状态码分布,403、429、5xx 的占比是否异常。
  6. 核对地域跳转规则,确认蜘蛛不会被来回送往不同地址。

CDN 和缓存层本身并不决定一条 URL 能不能被抓到,但它决定了蜘蛛每次抓到的到底是什么。把这一层理顺,抓取日志里的异常会少一大截,排查时也不用再在源站和边缘之间来回猜。