爬虫每次来訪,都會先問一次“這個頁面變了没有”。服務器怎么回答,决定了它是重新下载一遍整頁,還是收下一句“没變”就走。對蜘蛛池来说,這個细节直接關系到抓取效率:入口頁本身内容不多,却反复占掉抓取预算,目标頁就少了一次机會。
缓存头在爬虫眼里是什么
HTTP 缓存机制本来是為浏览器和 CDN 设計的,搜尋引擎爬虫同样遵守這套規則。它手里存着上次抓到的副本和對應的驗證信息,下一次請求时把這些信息带回来,服務器據此判断要不要重新發一遍正文。
- Cache-Control:告诉爬虫和中間层可以缓存多久。max-age 越長,爬虫越倾向于先不重新抓。
- ETag:頁面内容的指纹,用来做驗證式缓存。
- Last-Modified:頁面的最後修改時間。
- 304 Not Modified:驗證结果是没變,只回响應头,不回正文。
304 是省流量,還是被当成“没變化”
304 對爬虫是友好信号,說明頁面没動,它不必重算内容,這次抓取的成本也很低。但有两件事要注意:一是入口頁如果長期只回 304,它在你池子里的活跃度信号會趋于静止;二是有些自建服務把 304 回得含糊,比如正文其實換了但 ETag 没跟着更新,爬虫就會一直抱着舊副本的内容结构。
更常见的坑是反過来:動態生成的入口頁每次請求都返回不同的 ETag 或 Last-Modified,爬虫每次都被判為“已更新”,于是每次都拉全文。這類頁面在池子里數量一多,抓取预算被吃掉得很快,真正需要被發現的連結反而排在後面。
不同類型的入口頁怎么配
静態模板頁
内容基本不變,可以给較長的缓存時間,同时保持 ETag 稳定,让爬虫多數时候只做一次驗證請求。改動模板时记得让 ETag 跟着變,否則爬虫看不到這次更新。
動態生成的枢纽頁
這類頁面的作用是承载並輸出目标連結,連結结构可能随时調整,更适合用較短的缓存時間,或者用 no-cache 加驗證式缓存,保證爬虫每次都能拿到目前版本。
带跳轉或中間层的頁面
缓存头尽量和跳轉方式保持一致。如果响應头说可以缓存很久,而跳轉目标随时會改,爬虫和中間层就會各自拿着不同版本,之後排查問题會非常費劲。
配置时容易踩的几個坑
- 用随机數当 ETag:等于每次都告诉爬虫“内容變了”。
- Last-Modified 直接用目前時間:每次請求的時間都不同,同样造成“永遠在更新”的错觉。
- CDN 覆盖源站缓存头:源站改了没生效,或者反過来把不该長缓存的内容缓存了很久。
- 對 404、410 也返回長缓存:頁面已经撤掉,缓存里還挂着一份舊响應。
- 忽略 Vary:同一個 URL 按 UA 返回不同内容时,缓存可能串味,爬虫拿到的是给別人看的那一份。
几個可以照着做的建议
- 先固定住 ETag 的生成規則,用内容哈希,不要用時間戳或随机值。
- 内容没變就不要動 Last-Modified,改了内容再让它變化。
- 動態入口頁優先考虑短缓存加驗證式缓存,而不是一味拉長 max-age。
- 定期抽查响應头,用命令行工具直接看源站和 CDN 各返回了什么,確認没有被改寫。
- 把缓存头的設定和頁面的更新节奏對齐,改版时同步調整,別让两邊各说各话。
缓存头不是排名開關,它只是让爬虫少做無用功。省下来的预算能不能用在目标頁上,還要看連結结构和内容本身是否站得住。
小结
蜘蛛池入口頁的價值在于把爬虫顺利送到目标頁,而不是自己反复被完整抓取。把 ETag、Last-Modified 和 Cache-Control 配得稳定、可预期,爬虫就能少花力气在驗證上;反之,一個随机 ETag 就足以让整池頁面的抓取效率打折扣。配置完成後,建议结合訪問日誌看一段時間的抓取次數和响應碼分布,再决定是收紧還是放宽缓存策略。