不少站長在服務器日誌里看到大量 304 狀態碼,第一反應是:蜘蛛每次都来,但什么都没拿到,是不是抓取被浪費了?實际上,304 並不是错誤,也不代表蜘蛛白跑。它是 HTTP 缓存协商的结果,表示服務器確認资源没有變化,不需要重新传輸内容。
蜘蛛抓取中的缓存协商是什么
支持缓存协商的抓取工具,在重复訪問同一個 URL 时,通常會在請求头里带上缓存标识。常见的有两類:
- If-Modified-Since:带上上次抓取时服務器返回的 Last-Modified 時間。
- If-None-Match:带上上次抓取时服務器返回的 ETag 值。
服務器收到這些請求头後,會判断资源是否發生變化。如果没有變化,返回 304,不再返回正文;如果發生變化,返回 200 和新内容。這個過程對蜘蛛和普通浏览器都适用。
304 對抓取频率和抓取预算有什么影响
從服務器角度看,304 节省了带宽和响應時間。從蜘蛛角度看,一次 304 請求仍然會消耗一定的抓取請求次數,只是没下载正文。因此,它有助于把抓取预算用在別的 URL 上,但不會自動让蜘蛛更频繁地来訪。
如果頁面長期没有更新,蜘蛛收到 304 的次數可能會增多。有些情况下,它會适当降低對该 URL 的訪問频率,把時間分配给更新更活跃的頁面。這是正常的资源分配,不必把它理解成惩罚。
需要留意的是,304 次數多並不等于抓取效率一定高。如果頁面内容其實已经變化,但服務器仍然返回 304,蜘蛛就會繼續持有舊版本,更新自然很难反映到搜尋结果里。
Last-Modified 和 ETag 怎么配合
Last-Modified 表示资源最後修改時間,精度通常到秒。它實現简單,但有些動態頁面每次訪問都會生成目前時間,導致蜘蛛每次都被認為内容已變,于是频繁返回 200。
ETag 是内容标识,通常由服務器根據文件狀態生成。它比時間戳更精确,但同样要避免每次請求都變化。如果 ETag 由随机數或進程 ID 拼出来,蜘蛛每次拿到的值都不同,缓存协商就失去意义。
两者可以同时使用。蜘蛛一般會優先參考 ETag,再结合 Last-Modified 判断。配置时要保證同一個版本對應同一個标识,不要為了顯得更新而频繁改動這些头部。
几種常见誤区
- 把 304 当成软 404:304 表示资源仍然存在且未變,和空内容、错誤狀態不是一回事。
- 頁面刪除了却返回 304:如果 URL 已经不存在,應返回 404 或 410,而不是繼續用缓存头回應。
- 只靠 Sitemap 的 lastmod 催抓取:lastmod 是參考信号之一,但如果服務器缓存头告诉蜘蛛没變化,两者可能互相矛盾。
- 屏蔽蜘蛛訪問以便减少 304:這會直接减少抓取,得不偿失。
日誌里可以观察什么
在日誌中篩選蜘蛛的請求狀態碼,观察 200 和 304 的比例。如果某個栏目頁長期只有 304,說明内容更新少,可以检查是否真的没有變化。如果明明更新了却仍返回 304,就要检查 Last-Modified、ETag 以及中間缓存层是否配置正确。
同时關注响應時間。304 响應通常很快,但如果服務器在返回 304 之前仍执行了大量查询,實际负载並没有减轻。缓存头只是协议层優化,不能替代頁面生成效率的改善。
304 不是蜘蛛空手而归,而是它在確認頁面是否需要重新下载。站長要做的,是让這個信号和真實更新狀態保持一致。
總的来说,304、ETag、Last-Modified 属于基础但容易被忽视的抓取细节。把它們配置稳定,至少可以避免蜘蛛在頁面到底有没有變這件事上反复犹豫。至于它何时再来、抓多少次,仍取决于站点整体质量、更新节奏和其他抓取信号,没有一個头部能單獨决定。