搜尋抓取

缓存层與抓取:蜘蛛拿到的頁面是哪個版本

蜘蛛抓取的頁面往往不是源站直接返回的版本,而是经過 CDN 或反向代理缓存後的副本。本文梳理命中缓存、回源失敗、缓存键按 UA 分叉、错誤頁被缓存等情况對抓取的影响,並给出用蜘蛛视角自查與更新後主動刷新缓存的實用做法。

搜尋抓取

缓存层與抓取:蜘蛛拿到的頁面是哪個版本

排查抓取問题时,很多人只盯着源站:狀態碼對不對、HTML 有没有坏、内鏈通不通。但從蜘蛛發出請求到拿到 HTML,中間還隔着缓存與 CDN。這一层如果配置不一致,蜘蛛看到的頁面可能和用戶看到的不同,甚至和它上一次抓到的完全一样。

蜘蛛的請求先落在哪一层

常见鏈路是:蜘蛛 → DNS → CDN 邊缘节点 → 源站。如果邊缘节点上有可用副本,請求不會再回到源站。這意味着源站日誌里根本不會出現這次抓取,而蜘蛛拿到的可能是几小时甚至几天前的版本。只看源站日誌做抓取分析,很容易漏掉這一部分訪問。

命中與回源的区別

  • 命中缓存:响應快,源站没有日誌,返回内容取决于副本年龄,响應头里的 Age 可以反映這一点。
  • 回源:源站产生日誌,返回目前版本,但延迟更高、资源消耗更大。
  • 回源失敗:可能返回 5xx,也可能被缓存下来,在一段時間内持續影响抓取。

几類容易踩到的不一致

缓存時間设得過長

HTML 文档如果被設定了很長的 s-maxage 或 max-age,内容更新後邊缘节点仍返回舊版。蜘蛛再訪时看到的内容没變化,自然不會判断為更新過的頁面。動態頁面通常更适合短缓存加回源校驗,長缓存留给長期不變的资源。

缓存键把蜘蛛和用戶分開了

有些配置會按 User-Agent、Cookie 或设备類型区分缓存。如果蜘蛛的 UA 命中了另一份副本,你看到的頁面和它看到的可能不是同一份。响應里的 Vary 头能反映這類分歧,排查时要留意。缓存键分得越细,副本越多,不一致的概率也越高。

回源错誤被当成正常内容缓存

源站短暂 5xx 或超时,如果缓存規則把错誤响應也存了下来,蜘蛛接下来一段時間會持續拿到错誤结果。表現為源站已经恢复,抓取却仍然失敗。這類問题往往要等缓存過期才自行消失。

JS、CSS 被缓存层額外拦截

部分站点在 CDN 上對静態资源和脚本做了額外限制,蜘蛛拿不到完整的渲染资源,看到的頁面结构與實际不符。這類情况常常表現為抓取正常,但内容不完整。

用蜘蛛的视角做一次自查

  1. 用蜘蛛的 User-Agent 請求關键 URL,對比與浏览器請求返回的 HTML 是否一致。
  2. 查看响應头中的 Age、Cache-Control、X-Cache、CF-Cache-Status 等字段,確認是命中還是回源。
  3. 把源站日誌和 CDN 日誌對一遍,找出只有 CDN 有记錄、源站没有的抓取請求。
  4. 對同一 URL 连續請求两次,观察第二次是否返回同一份副本,判断缓存颗粒度。
  5. 在内容更新後立刻用蜘蛛 UA 請求一次,確認拿到的是新版本而不是舊副本。

缓存层與抓取稳定性的關系

缓存命中率下降时,回源請求會成倍增加,源站压力上升,超时和 5xx 的概率也随之變大。蜘蛛遇到连續的失敗响應會放慢节奏,短時間内就不再频繁回訪。所以缓存配置不只是性能话题,它間接决定了服務器能不能稳住抓取流量。

内容更新之後可以做的事

  • 更新重要頁面後,主動刷新對應 URL 的缓存,而不是等 TTL 自然到期。
  • 给 HTML 設定較短的缓存時間,把長缓存留给图片、字体這類不常變的资源。
  • 缓存键尽量简單,避免按 UA 分叉出多份 HTML 副本。
  • 让回源错誤不進入缓存,或者把错誤响應的缓存時間设得极短。
  • 服務器压力大的时候观察回源比例,命中率下降往往先于抓取異常出現。
缓存不是抓取優化的技巧,而是抓取鏈路上的一环。它决定了蜘蛛實际拿到什么,而不是你希望它拿到什么。

蜘蛛看到的頁面是整條鏈路末端的结果,源站只是其中一段。把 CDN、反向代理和源站三處的返回版本對一遍,很多“抓取正常但内容不對”的問题會變得容易解释,也更容易定位到具体该改哪一层。