蜘蛛池入口頁本身不复杂,通常就是一頁挂着若干 URL,等搜尋蜘蛛来取。但很多人在核對“日誌里明明有抓取,連結却没更新”时,會漏掉中間那一层——缓存。日誌里的 200,不代表蜘蛛拿到的是源站此刻生成的那份 HTML。
缓存可能出現在四個位置
- 浏览器與本地缓存:對蜘蛛影响相對小,因為爬虫通常不會長期复用本地缓存,但仍會參考 Cache-Control 等响應头。
- CDN 邊缘节点:最常见的一层。节点命中後直接返回舊副本,源站甚至看不到這次請求,日誌里自然也没有记錄。
- 反向代理或網關缓存:Nginx、Varnish 之類,規則配错时會把带參數的 URL 全部当成同一個资源處理。
- 應用层缓存:頁面片段、查询结果缓存,内容更新後需要等過期或主動清除才會生效。
按 UA 分流缓存最容易踩坑
有些站点為了让蜘蛛看到“干净版”頁面,會按 User-Agent 返回不同内容,並给不同 UA 設定不同缓存键。問题在于:部分 CDN 預設不把 UA 計入缓存键,于是蜘蛛拿到的可能是给普通訪客准备的版本;反過来,如果缓存键里带了 UA,而蜘蛛 UA 又存在多種變体,缓存命中率會掉得很低,源站压力立刻上升。
如果确實需要差异化返回,更稳妥的做法是把差异放在源站逻辑里,而不是靠缓存层判断 UA。缓存只负责同一份内容的高效分發,判断逻辑越简單越不容易出問题。
缓存给入口頁带来的三種具体影响
連結更新了,蜘蛛拿到的還是舊的
入口頁的主要作用是把新 URL 递出去。如果 CDN TTL 设成 24 小时,而你每小时更新一次連結列表,蜘蛛在大部分時間里看到的都是同一份舊 HTML。這不是蜘蛛不来抓,而是你递出去的還是上一批地址。
狀態碼也會被缓存
頁面临时返回 5xx,或者測試阶段返回過 404,如果被缓存层记下来,後續一段時間蜘蛛訪問得到的都是這個狀態碼。之前排查過的“蜘蛛掉头就走”,有相当一部分根因就在负缓存上。
同一路径出現多份内容
带參數的 URL 被規則归一化缓存後,不同參數可能返回同一個副本,蜘蛛會認為這些地址内容重复;反過来,如果缓存键包含随机參數或時間戳,同一逻辑頁會生成無數份副本,抓取预算被白白消耗。
排查顺序建议
- 用蜘蛛 UA 直接請求入口頁,對比返回内容與源站是否一致,重点看响應头里的 Age、X-Cache、CF-Cache-Status 一類字段。
- 對比服務器日誌與 CDN 日誌:源站日誌里没有的請求,多半在邊缘节点就被處理掉了。
- 检查缓存键規則,確認 URL 參數、Host、UA 是否被纳入。
- 確認 4xx、5xx 是否被缓存,以及對應的负缓存时長。
- 更新連結後主動刷新相關 URL,而不是等 TTL 自然過期。
配置上的几條建议
- 入口頁這類需要频繁更新的頁面,TTL 设短一些,几十分钟到几小时比較常见,具体看你的更新频率。
- 不要缓存 4xx 和 5xx,或把负缓存時間压到很短。
- 缓存键尽量只保留真正影响内容的维度,避免無意义參數和不稳定的 UA。
- 入口頁 HTML 保持“可缓存但可快速刷新”,與图片、CSS 這類長缓存资源区分開。
- 每次調整缓存規則後留出观察窗口,用日誌對比調整前後的抓取情况。
缓存不是敌人,它帮源站挡掉了大量重复請求。真正的問题在于:当入口頁需要“新鲜”的时候,缓存還在按舊規則工作。
把缓存当成蜘蛛鏈路上的一個參與者来看,很多“蜘蛛抓不到新連結”的問题會變得好解释:不是蜘蛛不来,而是它每次来都被同一份舊副本挡在门外。定期核對缓存規則與更新节奏是否匹配,比事後翻日誌猜测要省力得多。