蜘蛛不是只来一次
站点运营常把抓取理解成一次性的:URL 被發現、抓取、收錄,然後就結束了。實际蜘蛛對多數頁面是反复回訪的,回訪频率受内容更新节奏、頁面重要程度和服務器响應影响。回訪时,蜘蛛會带上條件請求头,服務器如果判断内容没變,返回 304。這一来一回看起来只是省流量,實际上决定了蜘蛛手里拿着的是哪一版頁面,也就間接影响了下一步會沿着哪些連結走。
條件請求的两種配對方式
- If-Modified-Since 配合响應头 Last-Modified,按時間判断。
- If-None-Match 配合响應头 ETag,按内容标识判断。
- 服務器判定未修改,返回 304,不带正文。
- 判定已修改,返回 200,重新下發完整 HTML。
蜘蛛拿到 304 後,通常會沿用上一次抓取到的正文来解析連結。304 决定的是用哪一版頁面,而不是路径本身。如果缓存里的那一版已经過时,蜘蛛就會繼續沿着舊連結走。
常见几種寫错的缓存头
Last-Modified 寫成目前時間
動態生成的頁面里,不少框架直接把請求時間輸出成 Last-Modified。這样每次條件請求都會被判定為已修改,蜘蛛每次都要重新下载完整頁面。带宽和抓取額度被白白消耗,長列表頁、篩選頁尤其明顯。
ETag 用時間戳或進程信息生成
用文件 inode、進程 ID、毫秒時間戳生成 ETag,多台服務器之間不一致,同一個 URL 每次返回的 ETag 都不同,條件請求永遠無法命中,回訪等于全新抓取。反過来,把全站模板统一塞一個固定 ETag 也有問题:蜘蛛認為所有頁面永遠没變,标题和正文改了也不會重新抓。
Vary 與 Cookie 把缓存切碎
如果 Vary 头按 User-Agent 或 Cookie 分缓存,蜘蛛拿到的可能是一個只有它自己见過的版本,里面的連結和其他用戶看到的並不一样。运营侧可以用固定 UA 請求一次,對比正文里的連結来驗證。
改版和 URL 迁移时最容易出問题
頁面正文没動,但模板變了:導航加了新栏目、換了一批内鏈、URL 结构調整並做了 301。如果服務器仍按老逻辑返回 304,蜘蛛手里還是舊版 HTML,里面是舊連結。這时候通常會出現两種情况:
- 蜘蛛繼續沿舊路径走,反复請求已经 301 的地址。
- 新頁面虽然進了 Sitemap,但没有任何内鏈指向它,被發現的速度被拖慢。
處理办法並不复杂:改版後主動让 ETag 或 Last-Modified 變化,比如把资源版本号寫進 ETag,让下一次條件請求返回 200。等蜘蛛拿到新版本,缓存自然會刷新。
CDN 與中間层要一並確認
不少站点前面有 CDN 或缓存代理,需要確認它對带條件头的請求是怎么處理的:有的會把 304 轉成 200 再补正文,有的會把不同来源的 ETag 合並成一個。這類行為在源站层面看不出問题,只能通過直接請求 CDN 节点来驗證。
运营侧可以自查的清單
- 抽样几條重要 URL,带 If-Modified-Since 和 If-None-Match 請求,看返回碼和 ETag 是否稳定。
- 看服務器日誌里 304 的比例。比例過低說明缓存头没生效;比例過高而内容明明在更新,就要查 ETag 是不是寫死了。
- 重点關注列表頁、栏目頁和導航接口,這些頁面的缓存版本决定了蜘蛛下一步能走到哪里。
- 把缓存刷新寫進發布流程,改版、換模板、調 URL 时都执行一遍。
304 的含义是内容没變、不用重传,不是蜘蛛不用来。路径的更新要落在正文和連結上,別指望缓存头替你做這件事。