蜘蛛第一次抓取某個 URL 後,過一段時間還會再来。再次来訪时,服務器返回 200 還是 304,看起来只是狀態碼不同,但會影响到這次抓取的带宽開销,也會影响蜘蛛把時間花在哪里。
再次抓取时的條件請求
如果服務器此前返回過 Last-Modified 或 ETag,蜘蛛下次請求同一 URL 时,通常會带上 If-Modified-Since 或 If-None-Match。這叫做條件請求。服務器收到後,可以判断内容有没有變化:没變化就回 304,變化了就回 200 並附上新内容。
304 省的是带宽,不是抓取次數
304 响應没有正文,传輸体积小,對服務器和蜘蛛都更轻。但要注意,它仍然是一次 HTTP 請求,仍然會占用一個抓取名額。所以 304 不會“节省抓取预算”到让蜘蛛少来,它节省的是带宽和解析成本。真正决定蜘蛛来不来的,還是内容更新频率、站点整体质量和服務器响應速度。
什么时候應该返回 200
- 頁面正文、标题、结构化資料有實际變化;
- 模板改了,導致頁面主要文本或内鏈發生變化;
- 此前没有正确返回 Last-Modified 或 ETag,無法做條件判断;
- 内容虽然没變,但狀態碼從 404 恢复為正常頁面。
如果内容确實變了,服務器却回 304,蜘蛛會繼續使用舊副本,新内容可能迟迟得不到更新。
常见的配置错誤
- Last-Modified 固定不變:有些程序把時間寫成安装時間,之後不再更新,蜘蛛會誤以為頁面從未變過。
- ETag 每次請求都變:比如把進程 ID 或随机數拼進 ETag,蜘蛛每次都得重新拿完整内容,304 形同虚设。
- 動態頁面一律回 200:内容没變也回 200,带宽浪費,蜘蛛拿到一堆重复内容。
- 304 之後又带正文:狀態碼和响應体不一致,可能让抓取工具判断異常。
和内鏈、Sitemap 的關系
304 只影响單個 URL 的重复抓取。Sitemap 里的 lastmod 是另一條线索,它告诉蜘蛛“這個 URL 大概什么时候變過”。如果 lastmod 寫的是很久以前,而服務器每次都回 304,两條线索一致,蜘蛛會降低回訪频率。如果 lastmod 频繁變動,服務器却總回 304,蜘蛛會逐渐不再信任 lastmod。内鏈结构也會影响:一個長期不變的栏目頁,如果每次都回 304,蜘蛛仍然會顺着它的連結去發現新 URL,但不會反复讀取正文。
從日誌里看缓存头是否生效
在服務器訪問日誌里,可以統計同一個 URL 的 200 和 304 比例。如果一個更新不频繁的頁面,蜘蛛来訪十次有九次都是 200,說明 Last-Modified 或 ETag 可能没設定好。可以重点检查:
- 响應头里有没有 Last-Modified 或 ETag;
- 同一個 URL 连續两次請求,ETag 是否稳定;
- 内容更新後,Last-Modified 是否跟着變;
- 304 响應的比例在稳定内容上是否合理。
不要為了“少让蜘蛛抓”而强行返回 304。蜘蛛需要看到真實的内容變化,强行回 304 只會让新内容延迟被發現。
把 304 和 200 用對,核心是让服務器如實告诉蜘蛛“内容變没變”。缓存头稳定、狀態碼诚實,蜘蛛就能把有限的抓取次數用在更有變化、更值得抓的 URL 上。