搜尋抓取

缓存层與蜘蛛抓取:CDN 返回的那份 HTML 是怎么被决定的

蜘蛛抓取到的,不一定是你本地看到的那份頁面。CDN、反向代理和缓存插件會在中間加一层,缓存命中、邊缘节点差异、被缓存的狀態碼都可能让蜘蛛拿到舊内容或错誤响應。本文梳理缓存层影响抓取的几種常见情况,以及用爬虫 UA 做驗證的排查顺序。

搜尋抓取

缓存层與蜘蛛抓取:CDN 返回的那份 HTML 是怎么被决定的

你看到的頁面,和蜘蛛拿到的可能不是同一份

本地打開正常、浏览器里内容是最新的,並不代表蜘蛛抓到的也是這样。請求從蜘蛛出發到你的源站,中間可能经過 CDN、反向代理、负载均衡、頁面缓存插件等多层。任何一层返回了缓存副本,蜘蛛拿到的就是那一份,而不是源站目前的内容。

抓取层面的問题往往不是“抓不到”,而是“抓到的是舊的或错的”。下面几種情况在排查日誌时比較常见。

缓存命中:蜘蛛拿到的是几天前的副本

如果頁面設定了較長的缓存時間,而更新时没有做主動刷新,缓存节点會繼續把舊 HTML 發给所有請求方,包括蜘蛛。表現是:你改了标题、正文或内鏈,蜘蛛再次抓取到的内容仍停留在舊版本。

更麻烦的是連結结构。新增的内鏈如果只出現在源站的新版本里,蜘蛛從缓存拿到的頁面里根本看不到這條連結,URL 發現自然就慢了一拍。

邊缘节点不一致:同一 URL,不同机房返回不同内容

多节点 CDN 在回源失敗、预热未完成或缓存過期時間不一致时,可能出現“A 节点是新版,B 节点是舊版”。蜘蛛的出口 IP 分布在多地,抓取结果就會时好时坏,日誌里表現為同一 URL 反复抓取、内容快照来回變化。

如果站点做了按地区返回不同内容(多語言、多货幣),但没有用 Vary 或獨立 URL 区分,缓存层會把某個地区的版本發给所有节点,蜘蛛看到的可能不是主版本。

被缓存的狀態碼:404 和 301 的残留

狀態碼同样會被缓存。上线過程中临时出現的 404、维護頁的 503、迁移时的 301,如果被缓存层记住了較長時間,即使源站已经恢复正常,蜘蛛仍然會持續拿到這個响應。

  • 临时 404 被缓存:蜘蛛把正常頁面当成死鏈,已發現的 URL 會被降频。
  • 301 被缓存:跳轉目标改了,蜘蛛還在按舊地址走。
  • 503 被缓存:蜘蛛判断站点不可用,整体抓取节奏放慢。

因此狀態碼的缓存時間通常要设得比頁面内容短,尤其是错誤响應。

几個和抓取直接相關的响應头

  • Cache-Control:决定内容在中間层停留多久。max-age 太長,更新後蜘蛛也會拿到舊版。
  • Vary:按 UA、Accept-Encoding 等维度区分缓存。忽略它,不同客戶端會互相串味。
  • ETag / Last-Modified:支持條件請求,蜘蛛可以用 If-Modified-Since 只取變更部分,减少無谓传輸。
  • Age / X-Cache:用来判断這次响應是命中缓存還是回源,排查时很有用。

用爬虫 UA 驗證,而不是只看浏览器

浏览器請求通常带 Cookie、走不同的缓存策略,看到的结果不能代表抓取结果。排查时按下面的顺序来:

  1. 用蜘蛛的 User-Agent 請求目标 URL,记錄狀態碼、响應头和正文摘要。
  2. 對比源站直连和走 CDN 的响應,看時間戳、内容長度是否一致。
  3. 換個出口 IP 或指定不同邊缘节点再請求一次,確認节点之間是否一致。
  4. 查看响應头里的 Age、X-Cache 等标记,確認是否命中缓存。
  5. 更新内容後主動刷新缓存,再重复第一步,確認蜘蛛能拿到新版。
  6. 對照服務器日誌里的蜘蛛請求记錄,確認它實际拿到的狀態碼分布。

哪些内容适合让缓存對蜘蛛“让路”

不是所有頁面都需要對蜘蛛穿透缓存。图片、样式、脚本這類静態资源,長缓存基本没有副作用;變化频繁的列表頁、首頁、詳情頁,缓存時間要短一些,或者更新时主動刷新。robots.txt 和 sitemap 文件建议用較短的缓存時間,規則變更後蜘蛛能較快讀到新版本。

缓存本身不是抓取問题,缓存和内容更新不同步才是。把“更新後多久缓存刷新”和“蜘蛛多久再来看一次”当成两件獨立的事来管,排查會清楚很多。

小结:抓取结果受中間层影响,而中間层往往是运维配置,不在内容編輯的视野里。出現“内容改了但抓取還是舊的”时,先確認蜘蛛實际拿到的响應,再回過头看缓存策略和狀態碼缓存,比反复調整内鏈更有效。