翻抓取日誌时,除了 200、3xx 和 5xx,304 出現的频率也不低。它通常不代表抓取失敗,而是蜘蛛在問服務器:“這個頁面我上次拿到的版本還在吗?”這一問一答,牵涉到站点如何给頁面打版本标记,也影响蜘蛛把時間花在哪里。
304 是怎么产生的
蜘蛛第一次抓到一個 URL,服務器返回 200 和頁面内容,同时可能在响應头里带上两個字段之一:Last-Modified 或 ETag。前者是頁面最後修改的時間,後者是服務器為這個版本計算出的一個标识。下次蜘蛛再来,會在請求头里带上對應的值,一般叫 If-Modified-Since 或 If-None-Match。
服務器收到後做比對:如果内容没有變,就回一個 304 Not Modified,正文不返回;如果變了,就回 200 並附上新内容。所以 304 的前提是站点支持條件請求,而且版本标记本身是可靠的。
两種校驗方式的差別
- Last-Modified:實現简單,精确到秒。如果頁面在几秒内多次修改,或者由程序動態生成時間,容易判断不准。
- ETag:基于内容或版本計算,粒度更细。但不同服務器生成規則不一样,有时集群里各台机器算出的 ETag 不一致,反倒让蜘蛛每次都拿到 200。
304 對抓取节奏意味着什么
很多人以為 304 是白跑一趟,其實它對双方都有意义。對站点来说,304 省掉了正文传輸,带宽和响應時間都更小;對蜘蛛来说,它用一次轻量請求確認頁面没變,可以更快把抓取額度挪去別的 URL。日誌里看到大量 304,通常說明站点的缓存校驗工作正常。
不過,如果整站几乎全是 304,而新頁面迟迟没有動静,就要反過来看:是不是新 URL 没有被發現,蜘蛛只能反复確認老頁面。這时問题不在 304,而在入口。
從日誌里看 304 是不是正常
抓取日誌一般有狀態碼、字节數、User-Agent、請求時間。可以按下面几步看:
- 筛出蜘蛛 UA 的請求,按狀態碼分组,確認 304 的占比。
- 把返回 304 的 URL 和返回 200 的 URL 放在一起看,是否覆盖了主要栏目。
- 如果某類頁面長期返回 200,而内容明明没變,检查响應头里有没有 Last-Modified 或 ETag。
- 如果同一 URL 在短時間内被重复請求多次,看是不是分頁、篩選參數或内鏈把同一個地址拆成了多個入口。
服務器配置上容易踩的几個点
一是動態頁面没有輸出校驗头,蜘蛛每次都要重新下载全文。二是 ETag 規則不一致,负载均衡後面多台机器各算各的,蜘蛛拿到的标记對不上,只能一直收到 200。三是中間有缓存层或 CDN,缓存的响應头被改寫,校驗值到源站對不上。四是頁面模板里带了會變化的時間戳,Last-Modified 每次都更新,但正文其實没動。
304 不是異常,也不是省事的開關。它更像一次確認:版本没變,就少传一次内容;版本變了,就该老老實實回 200。
怎么配合蜘蛛的校驗
對大多數内容站来说,让頁面正确輸出 Last-Modified 或稳定的 ETag 就够了。文章類頁面用發布時間作為 Last-Modified 比較稳妥;列表頁、首頁這類聚合頁面更新時間較频繁,可以按實际最後一次變動来标。重要的是不要让校驗值抖動:内容没動,标记就保持不變。
如果站点已经在用 Sitemap 或提交接口给蜘蛛提供新地址,那校驗机制管的是已知 URL 是否更新,和新 URL 發現是两條线,不要指望 304 去解决抓取入口的問题。
最後,观察 304 的變化趋势比盯單次請求更有用。改版、迁移或模板調整之後,304 比例突然掉得很低,往往說明响應头配置被改動了,值得回查一次。