运营中经常會遇到這種情况:某個老 URL 被蜘蛛發現後,先 301 到一個中間地址,中間地址又 302 到另一個域名,最後才落到真正的内容頁。對用戶来说只是多等了一下,對蜘蛛来说,這是一條需要连續走完的路径,中間任何一步出問题,這次抓取就可能停在半路。
一次跳轉,蜘蛛實际付出了什么
蜘蛛訪問一個 URL 的流程是:發起請求,拿到 3xx 狀態碼和 Location,再對新的地址發起一次請求。每多一跳,就多一次完整的往返等待——包括连接建立、等待响應头、再讀取内容。這些等待時間是叠加的,而不是並行完成的。服務器本来就不快的话,跳轉鏈會让原本勉强能抓完的頁面變成超时。
更關键的是,抓取机會是有限的。蜘蛛把预算花在跳轉上,就意味着留给真正内容頁的次數變少了。鏈條越長,末端那個頁面被完整抓到的概率越低。
哪几種重定向寫法最容易让路径散掉
- 鏈式跳轉:A→B→C→D,每一跳還跨域,连接要重新建立。
- 302 当永久迁移用:蜘蛛不确定要不要更新舊地址,可能反复回来訪問原 URL。
- 跳轉成环:A 跳到 B,B 又跳回 A,蜘蛛跟几跳後放弃。
- 跳轉终点是空壳:最终返回 200,但内容很少或為空,等于白走一趟。
- 入口地址不统一:HTTP 與 HTTPS、带 www 與不带 www、带尾斜杠與不带,互相横跳。
- Sitemap 與内鏈各寫一套:同一批内容出現多個入口,跳轉鏈彼此交叉。
怎么把跳轉鏈收敛到一跳
- 先确定全站唯一的規范地址,内部連結直接指向终点,不要為了省事寫成會跳轉的舊地址。
- 服務器层只保留一次 301,落点直接是最终 URL,中間不再中轉。
- 永久迁移用 301,临时活動或灰度頁用 302,两類不要混用。
- 核對 Sitemap、canonical、内鏈、常见外鏈是否都指向同一個终点。
- 用 curl -sIL 或訪問日誌看實际的 Location 鏈,把超過一跳的逐條收敛。
- 確認终点頁面返回 200 且内容完整,避免把蜘蛛引到一個空頁面。
一條命令看清跳轉鏈
在服務器或本地执行 curl -sIL -o /dev/null -w '%{url_effective} %{num_redirects}\n' https://example.com/old,可以看到跳了几次、最终落在哪個地址。批量检查时把老 URL 列表導進去逐個跑,很快就能找出那些跳了三跳以上的地址。
蜘蛛並不會因為跳轉本身受到什么特別對待,問题在于每次跳轉都在消耗有限的抓取机會。鏈條越長,真正要抓的内容越容易被排到後面。
服務器层面的配合
跳轉节点最好部署在响應稳定的机器上。如果 301 是由應用层生成的,要留意上游變慢时,连 3xx 都返回不出来,蜘蛛看到的就是 5xx 或连接被重置——這时鏈條是從第一步就断掉的,和跳轉次數無關。
抓取路径的本质,是從入口到内容的一串可预测請求。把重定向压到一跳、让所有入口指向同一個终点,能在不增加蜘蛛负担的前提下,让它更快走到你希望它看到的内容上。這件事不需要額外提交,只要把地址寫對、跳轉收敛,路径自然會顺。