蜘蛛抓取的时候,它請求的域名通常解析到 CDN 的邊缘节点,而不是源站服務器。這带来一個常被忽略的事實:蜘蛛拿到的頁面,未必是源站此刻生成的那一份,可能是节点上一次回源时缓存下来的副本。排查抓取異常时如果只盯着源站,很容易漏掉中間這一层。
蜘蛛的請求先落到哪里
一個請求大致會走這样的路径:DNS 解析到 CDN,节点先判断本地是否有可用的缓存副本。命中就直接返回,不再打扰源站;未命中則回源拉取,源站生成頁面,节点再按規則决定是否缓存、缓存多久。對蜘蛛来说,两種情况返回的都是 200,從前端看不出区別,但内容的时效性和稳定性可能完全不同。
缓存命中时,蜘蛛看到的可能是舊版本
如果 HTML 的缓存時間設定得比較長,而頁面内容更新频繁,节点在 TTL 内就會持續返回舊版本。蜘蛛可能在几小时内多次訪問同一個 URL,一次命中缓存、一次回源,拿到两份不同的内容。這種不稳定未必會直接導致什么問题,但會让“更新了却没變化”的判断變得困难——更新没被看到,不一定等于蜘蛛没来。
比較稳妥的做法是让重要頁面的缓存時間與更新频率匹配。栏目頁、首頁這類更新快的頁面可以短一些;常年不變的詳情頁可以長一些。内容有實质性更新时,主動刷新對應 URL 的缓存,比等待 TTL 到期更可控。
按 UA 或按地区分流,會放大差异
部分站点會在 CDN 上按 UA 区分返回内容,比如给爬虫一份精简版、给浏览器一份完整版。這種做法在短期内看似节省资源,但它让蜘蛛抓到的頁面與用戶看到的頁面出現分叉,長期看並不划算。
另一個容易出問题的地方是 Vary 头。如果把 Vary 设成包含 Cookie、語言、设备等過多维度,缓存會被切得很碎,甚至退化成几乎不缓存,回源压力上升。對需要被稳定抓取的 HTML 頁面来说,Vary 维度越少越好。
地区化内容也值得留意。给不同地区返回不同版本时,蜘蛛從哪個节点訪問、拿到哪一份,往往不受你控制。如果版本差异涉及主要正文,最好通過 URL 区分,而不是靠节点判断。
CDN 日誌與源站日誌各能說明什么
看抓取情况时,两邊的日誌都要看,但要知道各自的盲区。
- 源站日誌只记錄回源請求。如果节点大量命中缓存,源站會顯得“蜘蛛来得少”,但這不代表抓取没有發生。
- CDN 日誌记錄到達邊缘的請求,能看到抓取频次和 URL 分布,但通常看不到回源细节,也不一定区分命中與回源。
- 两邊對照,才能判断抓取量下降是蜘蛛真的少来了,還是被节点消化掉了。
可以定期检查的几項
- 確認需要被抓取的 HTML 頁面允许缓存,缓存時間與内容更新节奏對得上。
- 检查 Vary 头,去掉對抓取没有帮助的分化维度。
- 確認蜘蛛 UA 没有被單獨處理成另一套内容。
- 检查 CDN 侧的限速與防護規則,避免正常抓取被誤判成異常流量而返回 403 或 429。
- 確認回源失敗时的兜底策略。如果回源異常时节点返回错誤頁,而错誤頁又被缓存下来,影响會持續一段時間。
- 定期比對 CDN 日誌與源站日誌中的抓取记錄,確認請求鏈路没有断在中間层。
小结
CDN 不是抓取鏈路之外的旁观者,它本身就是鏈路的一部分。缓存策略、TTL、Vary 头、UA 處理規則,都會影响蜘蛛最终看到什么。把這些配置和日誌纳入日常检查,很多“抓取異常”會變得更容易定位。
排查抓取問题时,先問一句:蜘蛛的請求到底落在了哪一层?答案不同,接下来要查的東西也完全不同。