同一個 URL,站長在自己浏览器里看到的是 A 頁面,抓取日誌里记錄到的却是 B 頁面;或者同一批連結,一部分抓到了完整正文,另一部分只拿到骨架和占位内容。這類“抓取内容不一致”的問题,多數不是蜘蛛本身的行為異常,而是 CDN 與源站對爬虫 UA 做了两套處理,再加上缓存命中狀態不同,最终把不同版本的内容分發给了不同請求。
先把“不一致”定位到具体一层
在動配置之前,先確認差异出現在哪一层,否則很容易在错誤的位置反复調參。
- 直接訪問源站 IP 並带上 Host 头,绕過 CDN,看返回内容是否一致;
- 通過 CDN 域名訪問,但把 User-Agent 換成與抓取日誌中一致的爬虫 UA,观察响應是否變化;
- 對比首次請求(缓存未命中、回源)與二次請求(缓存命中)的响應体差异;
- 记錄响應头中的 Age、X-Cache、CF-Cache-Status 一類字段,判断這次請求是否真的走了缓存。
CDN 缓存是最常见的分叉点
CDN 可能按 URL 缓存,也可能把 UA、Cookie、Accept-Encoding 一起纳入缓存键。当缓存键包含 UA 时,爬虫與普通用戶的請求會落在两個獨立缓存條目上;如果源站對两類 UA 返回不同内容,缓存就會把差异長期固化。更麻烦的是,缓存條目一旦生成,源站後来修好的内容也可能因為缓存未過期而迟迟不更新。
需要重点確認三件事:缓存键里到底包含哪些维度、爬虫 UA 是否被單獨排除在缓存之外、缓存 TTL 是否長到足以掩盖源站的修复。
UA 分流規則常见的几種誤配
- 用“包含 spider/bot”這類宽松子串识別爬虫,把正常浏览器 UA 也誤判進去;
- 對识別為爬虫的請求返回精简版頁面、跳轉到静態快照,或直接给驗證頁;
- 規則只在部分节点或部分地区生效,導致同一 UA 在不同邊缘节点拿到不同内容;
- 分流規則與 robots.txt、X-Robots-Tag 各自獨立维護,改了一處忘了另一處。
建议的排查顺序
- 從抓取日誌里挑出内容異常的 URL,抽取請求時間、UA、Referer、响應大小與狀態碼;
- 用相同 UA 和相同請求头复現一次,確認問题可稳定复現而不是偶發;
- 绕過 CDN 直连源站再复現一次,判断問题在源站還是邊缘;
- 检查 CDN 缓存键配置與缓存命中狀態,必要时對相關路径做一次定向刷新;
- 检查邊缘的 UA 识別規則、WAF 規則與 Bot 管理策略,確認爬虫没有被降級處理;
- 检查源站是否存在基于 UA 的動態渲染或模板分支;
- 修复並清缓存後,用两種 UA 分別請求同一 URL,比對响應体是否收敛為同一版本。
修复與長期驗證
較稳妥的做法是让爬虫 UA 與普通用戶拿到同一份 HTML,把差异留给前端按需渲染,而不是在服務端生成两套结构。缓存键尽量只保留 URL 與必要的编碼维度,把 UA、Cookie 從键里剔除,避免缓存被切碎、同一條内容反复回源。
修复之後不要只看一次结果。建议保留一個抽样清單,定期用相同 UA 抓取同一批 URL,记錄响應体長度與關键内容指纹,一旦再次出現分叉就能第一時間發現。
抓取内容不一致时,先怀疑分發鏈路(CDN、WAF、UA 分流),再怀疑頁面本身。多數情况不是“蜘蛛抓不到”,而是“不同請求拿到了不同版本”。