很多人在蜘蛛池入口頁上啟用了缓存,本意是降低服務器压力、加快响應。但過一段時間發現:入口頁里明明新增了目标 URL,搜尋蜘蛛也来過,却没有去抓這些新連結。這时很容易怀疑“蜘蛛是不是被 304 挡住了”。要回答這個問题,先要理解搜尋蜘蛛抓取入口頁时,缓存是怎么參與判断的。
搜尋蜘蛛遇到 304 时,會發生什么
搜尋蜘蛛第一次抓取入口頁时,服務器一般返回 200,並带上 ETag 或 Last-Modified。蜘蛛會把頁面内容和這些标识一起存下来。下一次再抓同一個 URL 时,蜘蛛通常會带上 If-None-Match 或 If-Modified-Since 請求头,問服務器“内容變了没有”。
如果服務器認為没有變化,就返回 304 Not Modified,不带响應体。蜘蛛收到 304 後,會沿用本地缓存版本,通常不會重新下载和解析頁面。也就是说,304 本身不是错誤,它节省了带宽和抓取预算,但如果入口頁的連結已经更新,而服務器仍然返回 304,蜘蛛就可能繼續用舊版本,看不到新連結。
哪些缓存設定容易让新連結“迟到”
Cache-Control 的 max-age 太長
入口頁如果設定了很長的 max-age,中間层和蜘蛛都可能認為頁面長期有效。若你依赖頁面 HTML 里的連結發現目标 URL,建议對入口頁使用較短的缓存時間,或設定 no-cache 但允许 304 校驗。這样蜘蛛每次来都能確認頁面是否變化。
ETag 生成方式不稳定或過于稳定
有些服務器用文件修改時間、inode 或動態内容生成 ETag,頁面内容變了但 ETag 不變,蜘蛛就會收到 304;反過来,ETag 每次請求都變,蜘蛛又會反复下载完整頁面。比較稳妥的做法是让 ETag 與入口頁的連結内容相關,内容變化时 ETag 跟着變。
Last-Modified 没有随連結更新
如果入口頁是動態生成,但 Last-Modified 一直沿用舊值,蜘蛛會認為頁面没更新。動態入口頁可以考虑不發送 Last-Modified,只靠 ETag 或 Cache-Control 控制,避免给出错誤的“未修改”信号。
CDN 或反向代理缓存未刷新
入口頁套了 CDN 後,蜘蛛訪問到的是 CDN 节点。若 CDN 缓存了舊 HTML,即使源站已经更新,蜘蛛拿到的仍是舊版本。需要確認 CDN 的缓存規則、刷新机制,以及回源时是否按正确的主机头和後端路径取内容。
怎么排查入口頁 304 是否影响新連結發現
- 用 curl -I 或浏览器開發者工具查看入口頁响應头,確認是否返回 304,以及 Cache-Control、ETag、Last-Modified 的值。
- 在入口頁新增一條明顯的測試連結,再請求一次,看响應头里的 ETag 或 Last-Modified 是否變化。
- 检查 CDN 和反向代理的缓存命中情况,必要时手動刷新入口頁 URL。
- 在服務器日誌中观察入口頁的 304 比例。如果長期大量 304,同时新連結迟迟不被抓,就需要調整缓存策略。
- 新增目标 URL 後,配合 sitemap 更新、主動提交或頁面内容變更,让蜘蛛有理由重新抓取入口頁。
304 不是敌人,關键是“内容變化要能被發現”
對搜尋蜘蛛来说,304 可以节省抓取资源,本身不是坏事。真正要避免的是:入口頁已经新增了連結,但服務器、CDN 或缓存层仍然告诉蜘蛛“没變化”。只要你让入口頁在連結更新时产生可识別的變化,並给蜘蛛留出重新抓取的路径,304 就不會成為 URL 發現的障碍。
如果你的蜘蛛池入口頁更新频繁,建议把缓存校驗做好:内容變,标识變;内容不變,再返回 304。這样既省资源,也不耽誤搜尋蜘蛛發現新目标 URL。