發現和抓取不是同一個動作
搜尋蜘蛛從入口頁解析出 a 标簽的 href 後,第一件事是把連結放進待抓取队列,這时候记下的通常就是 href 里寫的地址。只有真正發起請求之後,它才會遇到跳轉,並根據响應头里的 Location 繼續往下走。所以“入口頁寫了什么”和“最终抓到了什么”,在日誌里经常是两條不同的记錄。
如果最终地址返回的是 200,搜尋蜘蛛一般會把内容和 URL 归属到這一跳的地址上,而不是入口頁里最初寫的那個。這也是很多站点在日誌里看到舊地址有請求、新地址却没有稳定抓取记錄的原因之一。
301 和 302 的處理差別
301 表示永久跳轉,搜尋蜘蛛通常會把原地址的信号逐步轉移到新地址,後續也更可能直接抓取新地址。302 是临时跳轉,處理上更保守,原地址仍然會保留在队列里,被反复請求的概率更高。
對入口頁来说,這意味着同一個目标頁,用 301 指向和用 302 指向,長期表現可能完全不同。如果你在入口頁里给目标 URL 挂了一层 302,又同时用別的方式提交了最终地址,两個地址都會出現在抓取队列里,白白占掉一部分請求額度。
跳轉鏈太長會带来什么
- 每一跳都要額外發一次請求,抓取预算被一层层摊薄;
- 中間任意一环超时、返回 5xx,整條鏈就断在那里;
- 跳轉层級太深时,最终頁面可能只被部分抓取;
- 带參數的跳轉容易在某一跳丢掉 utm、分頁或路径後缀;
- 鏈路里如果有移動端适配或区域判断,還可能跳到另一個版本的 URL。
跨域跳轉要注意的细节
入口頁在 A 域、最终頁在 B 域,搜尋蜘蛛照样會跟進,但归属會落到 B 域的地址上。用 301 时,A 域入口頁积累的信号會向 B 域传递;用 JS 跳轉或 meta refresh,處理方式又不一样。這里的關键不是“能不能跟”,而是你要提前想清楚希望哪個域名、哪條路径被记住。
几種常见的 URL 混乱场景
- 入口頁 href 寫的是舊域名,跳轉後落到新域名,日誌里新舊地址都出現請求;
- 跳轉地址里带 session id 或随机參數,每次抓到的最终 URL 都不一样;
- 同一目标在入口頁里既寫了直连連結,又寫了一條跳轉連結,队列中出現两條记錄;
- 跳轉落点是需要登入或受地区限制的頁面,蜘蛛抓到的是拦截頁而不是正文;
- 跳轉目标是带尾斜杠和不带尾斜杠的两個版本,被当成两個地址處理。
一套可执行的排查顺序
- 先用 curl -I 看入口頁 href 那一跳返回的是 200 還是 3xx;
- 顺着 Location 一直跟到最後一跳,確認最终狀態碼和最终 URL;
- 把服務器日誌里蜘蛛請求的地址,和手動跟出来的最终地址逐條對照;
- 重点检查參數是否丢失、域名大小寫、路径尾斜杠、http 與 https 的差异;
- 在表格里把“發現地址”和“最终抓取地址”分成两列,不要混记成一條。
整理入口頁連結时的几個习惯
能直连就不要绕跳轉,尤其是入口頁這種主要承担發現任務的位置。确實需要跳轉时,把层級控制在 1 跳以内;跨域跳轉尽量用 301,並保持路径结构可预测;不要在跳轉過程中附加随机參數或临时追踪碼;入口頁連結定期過一遍,避免長期指向已经下线的舊地址。
跳轉本身不會阻止 URL 被發現,但它會改變最终被记錄下来的那個地址。與其纠结搜尋蜘蛛跟不跟,不如先把入口頁里每條連結的落点確認清楚。