做蜘蛛池或需要批量发现 URL 时,常见一种做法:入口页链接一个短链或中转地址,再由这个地址 301 或 302 跳到真正的目标 URL。这时问题就来了——搜索蜘蛛会不会跟着跳转走到最终页面?中间跳几层它会放弃?跳转后的地址还算不算被发现?这一篇把 HTTP 跳转和 URL 发现之间的关系拆开说。
搜索蜘蛛通常会跟进 HTTP 跳转
搜索蜘蛛请求一个 URL 后,如果服务端返回 301 或 302,并带上 Location 响应头,它一般会按 Location 再发一次请求,直到拿到 200 的页面,或遇到终止条件(超时、错误、循环、被规则拦下)。也就是说,入口页里链接的中转地址本身会被抓,跳转后的目标通常也会被继续请求,两者都可能进入抓取队列。
但要清楚一点:跟不跟、跟到第几层,不由你指定,而是搜索引擎自己的抓取规则和当时的抓取预算决定的。跳转不是加速开关,它只是把一次请求变成两次。
301 和 302 传递的信号并不一样
301 表示永久跳转,通常被理解为这个地址以后再也不用,内容已搬到新地址。搜索引擎倾向于把两个 URL 当作同一份内容的两个位置处理,相关信号可能归到最终地址上。302 是临时跳转,处理上更保守,原地址仍可能保留在索引中,最终地址是否被单独当作可收录 URL,反而不确定。
如果你的目的只是让目标 URL 被搜索蜘蛛发现,那么中转地址返回什么状态码,会影响它被对待的方式:
- 希望稳定指向新地址、不让中转地址长期占位,用 301;
- 只是临时分流、统计或做 A/B,用 302,但别把它当长期方案;
- 跳转到一个与入口页主题完全无关的页面,容易被判为异常。
跳转链太长会发生什么
一跳到底通常没问题,但如果 A 跳到 B、B 跳到 C、C 再到 D,风险会累积:
- 每一跳都是一次请求,持续消耗抓取配额,尤其是入口页和最终站同属一个抓取预算时。
- 链路中任何一环出现超时、5xx 或循环跳转,蜘蛛就会停下,最终地址根本没被请求。
- 层级过深时,部分抓取策略会主动截断,只记录前几跳。
实践中把跳转控制在 1 跳、最多 2 跳,能明显减少不确定性。
别把发现和抓取混为一谈
要区分两件事:发现和抓取。入口页里出现的中转地址被解析到,只是发现了它;搜索蜘蛛是否真的请求它、再沿 Location 请求最终地址,取决于抓取优先级和配额。一个低优先级的中转地址,可能躺在队列里很久也没被请求。
另外还有一层差别:如果入口页链接的是最终地址,最终 URL 就是被直接发现的;如果链接的是中转地址,最终地址是经由跳转间接发现的,链路上多了一个可能失败的环节。中转地址一旦失效、被删、被拦,后面的目标 URL 也跟着断了。
几个容易踩的坑
- 用 JavaScript 或 meta refresh 做跳转:跟进依赖渲染,比 HTTP 状态码跳转更不确定。
- 跳转目标被 robots.txt 屏蔽:蜘蛛跟过去也会被拦下,不产生实际抓取。
- 跳转链带随机参数:每一跳都可能生成新 URL,容易被当成大量新地址反复抓取。
- 中转地址返回 200 的中间页而不是真跳转:蜘蛛只会停在中间页,不会继续到目标。
- HTTP 与 HTTPS 混跳、带与不带 www 混跳:能跳,但会给链接判断和抓取增加额外环节。
用跳转做 URL 分发不是错,但它把发现链路拉长了。确定要长期被发现的地址,尽量直接放在入口页的可点击链接里,跳转留给确实需要统计或临时分流的场景。
可以落地的检查清单
- 用命令行工具或抓取工具看中转地址返回的状态码和 Location,确认是 301/302,而不是 200 的中间页。
- 确认跳转链只有 1 到 2 跳,且每一跳都能正常返回。
- 确认最终地址返回 200,且没有被 robots.txt 或 noindex 层面的规则挡住(前提是你确实希望它被抓取)。
- 在入口页同时保留最终地址的直接链接,减少对跳转链的依赖。
- 看服务器日志,确认最终地址是否真的被请求过,而不是只请求了中转地址。
总的来说:搜索蜘蛛一般会跟进 HTTP 跳转,但跟进过程不受你控制,跳转越多、越绕,最终地址被抓到的机会越不确定。把跳转当成分发手段之一,而不是唯一的发现路径,会更稳妥。