為什么回訪比首次抓取更值得關注
新頁面發布後,大家關心的通常是“蜘蛛来没来”。但一個頁面在生命周期里,被抓取的次數大部分来自回訪。蜘蛛判断要不要重新處理一個 URL,核心問题是:内容變了没有。如果服務端能明确告诉它“没變”,它可以省下一次完整下载和解析;如果每次都只能说“變了”,它就只能把整頁内容再拉一遍。
條件請求是怎么运作的
蜘蛛回訪时,會把上次抓取记錄下的信息带回来:
- If-Modified-Since:基于上次响應中的 Last-Modified 時間。
- If-None-Match:基于上次响應中的 ETag 值。
服務端把這两個值和目前内容比對:一致就返回 304,不返回正文;不一致就返回 200 和完整内容。這里有個容易被忽略的点:304 减少的是传輸量,不是請求次數。蜘蛛仍然發起了一次抓取,只是拿到的正文更少,它不會因為 304 就给你更多抓取机會。
三種常见的配置問题
Last-Modified 每次都不一样
有些站点的 Last-Modified 取的是頁面生成時間、模板渲染時間,或者 CDN 回源時間。结果是同一篇没改過的文章,每次請求返回的時間戳都在變,條件請求永遠不命中,蜘蛛每次都得下载全文。
ETag 在多台机器上不一致
部分服務器預設用文件 inode、磁盘路径甚至進程信息生成 ETag。多机、多容器部署时,同一個 URL 在不同节点算出的值不同,蜘蛛带着上次的值回来命中不了,同样只能走 200。
内容没變却上报“變了”
首頁和列表頁最容易出現這種情况:推荐位、訪問計數、時間格式化每次都在變。如果這些變動被算進 Last-Modified 或 ETag,蜘蛛每次都會判断頁面已更新,然後反复抓取一份實质上相同的内容。長期下来,既浪費了抓取量,也會让它對站点的更新节奏形成错誤印象。
可以怎么改
- Last-Modified 用内容的真實更新時間(例如資料库里的 updated_at),不要用請求時間或渲染時間。
- ETag 用正文内容算哈希,保證同一份内容在不同节点得到相同结果。
- 只有内容确實變化时才更新這两個值,格式調整、計數變化不算内容變化。
- 列表頁與首頁的變化可以接受,但要控制變動频率和幅度,別让每次訪問都像新頁面。
- HTML 頁面和静態资源分開處理,静態资源的長缓存策略不要直接照搬到動態頁面上。
怎么驗證配置是否生效
最简單的办法是手動模拟一次條件請求:先记下响應头里的 Last-Modified 或 ETag,再次請求时把它带上,看服務端是否返回 304。也可以回到日誌里看同一個 URL 的狀態碼分布——如果大量 200 响應的字节數几乎一样,往往說明條件請求没有起作用。
別把 304 当成優化目标
304 的價值是减少重复下载和解析,让服務器和蜘蛛都省一点力气,但它不會带来更多抓取。真正决定抓取表現的是站点整体质量、内容更新节奏、服務器响應稳定性這些基础項。
條件請求是给回訪“减负”的手段,不是给抓取“加量”的手段。它解决的是重复传輸,不解决内容是否值得抓。
和其他抓取因素的配合
304 要和服務器响應速度一起看:一個耗时两秒才返回的 304,比一個快速返回的 200 更拖累抓取。它也不影响 URL 發現——内鏈和 Sitemap 该暴露的路径還是要暴露。把這几件事分開處理,抓取路径才不會被一個细节卡住。