你看到的頁面,和蜘蛛拿到的可能不是同一份
本地打開正常、浏览器里内容是最新的,並不代表蜘蛛抓到的也是這样。請求從蜘蛛出發到你的源站,中間可能经過 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、走不同的缓存策略,看到的结果不能代表抓取结果。排查时按下面的顺序来:
- 用蜘蛛的 User-Agent 請求目标 URL,记錄狀態碼、响應头和正文摘要。
- 對比源站直连和走 CDN 的响應,看時間戳、内容長度是否一致。
- 換個出口 IP 或指定不同邊缘节点再請求一次,確認节点之間是否一致。
- 查看响應头里的 Age、X-Cache 等标记,確認是否命中缓存。
- 更新内容後主動刷新缓存,再重复第一步,確認蜘蛛能拿到新版。
- 對照服務器日誌里的蜘蛛請求记錄,確認它實际拿到的狀態碼分布。
哪些内容适合让缓存對蜘蛛“让路”
不是所有頁面都需要對蜘蛛穿透缓存。图片、样式、脚本這類静態资源,長缓存基本没有副作用;變化频繁的列表頁、首頁、詳情頁,缓存時間要短一些,或者更新时主動刷新。robots.txt 和 sitemap 文件建议用較短的缓存時間,規則變更後蜘蛛能較快讀到新版本。
缓存本身不是抓取問题,缓存和内容更新不同步才是。把“更新後多久缓存刷新”和“蜘蛛多久再来看一次”当成两件獨立的事来管,排查會清楚很多。
小结:抓取结果受中間层影响,而中間层往往是运维配置,不在内容編輯的视野里。出現“内容改了但抓取還是舊的”时,先確認蜘蛛實际拿到的响應,再回過头看缓存策略和狀態碼缓存,比反复調整内鏈更有效。