入口頁里放一條連結,目标地址却不是直接返回 200,而是先 301 到 A,A 再 302 到 B,最後才落到真正的内容頁。這種结构在蜘蛛池和站点运营里很常见,通常不會让抓取彻底失敗,但會让“發現”這件事變得不那么干脆。
搜尋蜘蛛遇到跳轉时的一般處理
搜尋蜘蛛請求一個 URL 时,如果拿到的响應碼是 3xx,它會讀取响應头里的 Location,然後對新地址再發一次請求。這個過程會重复,直到拿到 200、404、403 這類最终响應,或者触及引擎内部的跳轉次數上限後停止跟随。
有几点值得先记住:
- 跳轉次數的上限各引擎都不公開,普遍認為在 5 跳左右,超過就容易被放弃;
- 爬虫一般不會把鏈條中間每一跳都当成獨立頁面收錄,最终地址才是它真正要评估的對象;
- 相對路径的 Location 會按目前 URL 解析,如果中間發生域名切換,容易解析到意料之外的地址;
- 只要某一跳返回 4xx 或 5xx,鏈條就断在那里,後面的地址不會被請求。
301 和 302 的差別有多大
從“能不能被發現”這個角度看,两者都會被跟随,差別更多体現在信号归属和後續行為上。301 通常被视為永久迁移,引擎倾向于把原先指向跳轉起点的信号归到终点;302 被视為临时,虽然也會跟,但引擎會保留原来的记錄,並可能持續回来检查起点是否恢复。對运营来说,如果迁移是确定的,用 301;如果只是临时切換或 A/B 測試,用 302,但要知道它不會帮你把起点上的歷史记錄清理干净。
對 URL 發現的實际影响
入口頁上那條連結本身仍然是有效的發現信号,蜘蛛确實會因為点击它而開始一次請求。真正被影响的是後續成本:從“入口頁到目标地址”變成“入口頁到跳轉再到跳轉再到目标地址”,多出来的每一次請求都要占用抓取配額和時間。
跳轉鏈越長,蜘蛛在單個目标上消耗的预算越多,同一時間能覆盖的 URL 數量就越少。如果你在观察“為什么這批 URL 發現得很慢”,鏈路長度往往是一個容易被忽略的變量。
另外,鏈條中間的地址也會出現在服務器日誌里,看上去像“蜘蛛在抓一個已经不用的舊頁面”,其實那只是鏈路中的一环,不代表它對這個舊地址有額外兴趣。
日誌里怎么判断蜘蛛跟了几跳
- 按時間顺序,把同一個爬虫 User-Agent 對同一批路径的請求排出来;
- 如果 /old-a 之後紧接着 /new-b,再紧接着 /final-c,狀態碼依次是 301、302、200,基本可以確認是一條鏈;
- 注意区分跳轉鏈和獨立抓取,结合 Referer 和請求間隔来看會更稳;
- 如果日誌里只看到第一跳、没有後續請求,通常說明鏈條在某一环断了,或者跳轉次數已经触到上限;
- 如果看到同一對地址反复来回出現,先怀疑循环跳轉。
容易踩的几個坑
- 循环跳轉:A 到 B、B 回到 A,蜘蛛會绕几圈後放弃,等于這條連結白放;
- 终点被屏蔽:终点正好落在 robots.txt 禁止的目錄,前面几跳全白跑;
- 终点不是内容頁:跳到登入頁、驗證頁或错誤提示頁,蜘蛛拿到的並不是你希望它看到的東西;
- 跳轉目标動態變化:按 UA、按 IP、按時間随机跳,日誌难以复現,問题也很难定位;
- 机制混用:301 後面接 meta refresh 或 JavaScript 跳轉,等于把鏈路拆成两套規則,可预测性更差。
更省事的做法
- 把跳轉收敛成一次,直接 301 到最终地址,不要再套第二层;
- Location 尽量使用绝對地址,避免解析歧义;
- 保證终点稳定返回 200,不要时好时坏地一會儿 200 一會儿 302;
- 確認终点没有被 robots.txt 或 X-Robots-Tag 拦截;
- 蜘蛛池入口頁尽量直接指向终点,而不是指向跳轉的起点。
跳轉鏈不是不能有,而是它會让發現過程多绕几圈。鏈路越短,蜘蛛越省事,你在日誌里看到的現象也越清楚。
小结
多級跳轉的核心問题不是“能不能被抓”,而是“抓得值不值”。蜘蛛會沿着 Location 一跳一跳走下去,但每多一跳就多一次請求、多一份预算消耗,也更容易在中途因為 4xx、超上限或屏蔽而中断。把入口頁到目标地址的路径压到一跳,並保證终点稳定可訪問,是排查這類問题时最直接、也最容易驗證的做法。