做站点运营时,URL 跳轉几乎是绕不開的:換域名、上 HTTPS、统一 www、给列表頁补上尾斜杠,都會产生 301 或 302。單次跳轉本身不是問题,搜尋蜘蛛能正常跟随。真正影响抓取效率的,是一條鏈上串了太多跳轉:從舊地址出發,要经過三四次响應才落到最终返回 200 的頁面。
一次跳轉和四层跳轉,差別在哪
蜘蛛拿到一個 URL 时,期望的是尽快拿到内容。如果第一次响應是 301,它會记下新地址並繼續請求;再来一個 301,再来一個。每一次都算一次獨立的 HTTP 請求,都要占用连接、時間與抓取配額。鏈越長,同一個目标頁面被看到的時間越晚,抓取预算也被摊得越薄。
更麻烦的是,如果中間某一跳返回的是 302、meta refresh 或 JS 跳轉,蜘蛛對它們的處理並不一致:302 常被当作临时狀態反复確認,JS 跳轉則需要進入渲染流程才有机會被發現。鏈路上只要有一环卡住,後面的目标頁就很难被稳定抓到。
站内跳轉鏈通常是這样堆起来的
- HTTP 到 HTTPS 一跳,再加上 www 與非 www 一跳,合並成两层;
- 舊域名整体迁移时,規則寫成舊域名到中間域名、再到新域名;
- CDN 或负载层配了一條跳轉,源站又配了一條,两层叠加;
- 頁面里的手寫連結指向带參數的舊地址,舊地址再跳到規范地址;
- 大小寫、尾斜杠、預設頁各自触發一次归一化跳轉。
蜘蛛跟随跳轉时大致會做這几件事
- 請求原 URL,拿到 3xx 狀態碼與 Location 头;
- 把新地址放進待抓取队列,等待下一轮調度;
- 若新地址又返回 3xx,繼續入队,直到拿到 200 或明确的错誤碼;
- 最终頁面被解析後,其中的連結才進入後續的 URL 發現流程。
可以看出,跳轉鏈一般不會让 URL 彻底丢失,但會把它往後排。對于本来就抓取频率不高的站点,一串跳轉可能意味着目标頁要等上更久,列表頁里的新連結也跟着延迟被發現。
排查一條鏈有多長
最直接的方式是用命令行查看完整鏈路:curl -IL 地址 會依次打印每一跳的狀態碼與 Location,注意是否出現循环、是否终止于 200。
接着對照服務器日誌,篩選 301 與 302 的訪問记錄,看哪些地址被反复請求、哪些每次都跳到同一個目标。也可以检查 Sitemap 與内鏈里寫的是不是最终地址:如果站内連結指向的是會跳轉的舊地址,那蜘蛛每抓一次就多走一步,日誌里的 3xx 數量也會明顯偏高。
處理原則:让跳轉尽量短
- 能合並的規則合並,让一次跳轉直接落到最终地址;
- 站内連結、Sitemap、規范标簽一律使用最终 URL,不再指向跳轉地址;
- 临时性變更用 302,永久性迁移用 301,不要把 302 長期挂着;
- 避免用 meta refresh 與 JS 做主要跳轉,它們對蜘蛛的可见性不如 3xx 直接;
- 迁移期結束後清理舊規則,防止鏈條越留越長。
變更之後別忘了复检
每次改版、切換 CDN、上线新的跳轉規則之後,抓取路径都可能悄悄變長。建议固定几條典型入口 URL,比如首頁、一個栏目頁、一個詳情頁,定期用 curl 检查跳轉层數,同时观察日誌中 3xx 的比例是否上升。3xx 占比異常升高,往往說明某條規則被叠加了,或者站内又開始大面积引用舊地址。
跳轉不是错誤,层层跳轉才是成本。让蜘蛛用最少的請求拿到最终頁面,本身就是一種抓取效率上的優化。