入口頁更新了目标連結之後,如果抓取日誌里搜尋蜘蛛的訪問记錄看起来“毫無變化”,很多人的第一反應是蜘蛛没来抓。但更常见的情况是:它来了,也确實讀了頁面,只是拿到的 HTML 不是你以為的最新版本——中間隔了一层 CDN 或反向代理缓存。
搜尋蜘蛛和浏览器請求的不是同一份内容
你在浏览器里打開入口頁,請求可能带 cookie、走回源、命中本地或私有缓存;搜尋蜘蛛請求时通常不带 cookie,走的是 CDN 邊缘节点,命中的是面向所有訪客的公開缓存版本。如果缓存键不区分這些差异,邊缘节点很可能把很久以前的 HTML 直接返回。
缓存本身没有错。問题在于入口頁的連結属于“會變的内容”,而缓存策略常常是按“不會變”来配置的,两者一旦错位,就會出現“源站已改、蜘蛛仍讀舊版”的現象。
怎么確認拿到的是舊版本
用命令行直接看响應头
用 curl -I 带上搜尋蜘蛛的 UA 請求入口頁,重点看 Cache-Control、Age、X-Cache、CF-Cache-Status 這類头。Age 數值很大,基本說明命中了較老的缓存。再用 curl 拉一次完整正文,和源站目前生成的内容做對比。
對比抓取日誌里的响應大小
如果日誌记錄了响應字节數,把最近几次抓取的字节數和目前頁面實际大小對一下。如果差別明顯且長期稳定,而不是随机波動,那大概率就是缓存层返回了固定舊版本。
用抓取測試工具看實际 HTML
部分站長工具會展示蜘蛛實际拿到的 HTML。注意看里面有没有新加的連結、舊連結是不是還在。看清楚“蜘蛛看到什么”,比盯着訪問次數更有意义。
常见的缓存配置誤区
- Cache-Control 里的 s-maxage 设得很長,邊缘节点几天都不回源;
- 缓存键没有把查询串或 UA 纳入,動態參數被整体忽略;
- 源站更新後没有主動刷新缓存,只是等自然過期;
- CDN 面板里另有一层頁面規則,覆盖了源站返回的缓存头;
- 入口頁本由程序動態生成,却被当成静態资源長時間缓存。
這里要提醒一点:不建议专门针對搜尋蜘蛛的 UA 單獨返回不同内容,那属于 cloaking 的方向,風險遠大于收益。正确的目标應该是對所有訪客都返回同一份最新内容,而不是给蜘蛛開小灶。
更新入口頁連結时的稳妥顺序
- 先改源站,確認直接訪問源站时已经是新版本;
- 主動刷新 CDN 缓存,或者把入口頁的缓存時間設定得短一些;
- 入口頁這類索引型頁面可以配較短的 s-maxage,配合 stale-while-revalidate 使用;
- 刷新之後,用带蜘蛛 UA 的請求复查一次,確認拿到的是新 HTML;
- 再观察几天的抓取日誌,看蜘蛛是否讀到了新連結。
別把缓存問题和抓取频率低混在一起
如果蜘蛛本来就很少来,那首先要解决的是入口頁的可抓取性和更新节奏,缓存只是其中一环。两者的表面現象很像——舊連結一直在被訪問——但處理方向不同:一個是内容分發問题,一個是抓取調度問题。先判断属于哪一類,再動手改配置,能少走不少弯路。
缓存舊版本還有一個副作用:你明明已经删掉的舊連結仍然被抓,日誌里 404 數量上升,容易让人誤以為站点出了新問题。排查时先確認“蜘蛛讀到的到底是哪一版頁面”,很多疑問會立刻清晰。
缓存解决的是“蜘蛛看到什么”,不解决“蜘蛛来不来”。把這两层拆開看,排查效率會高很多。