蜘蛛的抓取队列是按 URL 排的,不是按「页面」排的。同一份内容如果存在多个可访问地址,每个地址在蜘蛛眼里都是一个独立的待抓取对象。URL 规范化(也叫 URL 归一化)要解决的,就是把这些地址尽量收敛成少数几个,让抓取资源用在真正需要的地方。
重复地址通常从哪来
在排查之前,先知道常见的重复形态,多数站点的重复并不是内容复制,而是入口写法不统一:
- 协议与主机差异:http 与 https、带 www 与不带 www 同时可访问。
- 路径大小写不同,例如 /About 和 /about 都能打开。
- 尾斜杠差异:/list 与 /list/ 返回同一页。
- 默认文件名:/ 与 /index.php、/index.html 并存。
- 参数组合:排序、筛选、追踪参数、会话 ID。
- 附属版本:打印页、移动版、AMP 版各有一个地址。
抓取之前的初步归一
在真正发出请求之前,蜘蛛通常会对 URL 做一轮机械处理:协议和主机名转小写、去掉默认端口、解析相对路径、去掉 # 后面的片段(片段不会发送给服务器)。但这只是文本层面的归并。只要服务器对两个地址都返回了内容,它们仍然可能被分别抓取,所以这轮处理只能减少一部分重复,剩下的要靠站点自己给信号。
决定收敛的三个信号
301 跳转
最直接的信号。让其中一个地址返回 301,指向你希望保留的那个,蜘蛛跟着跳转后,通常会把权重和抓取记录归到目标地址上。注意两点:跳转要一步到位,不要 A→B→C;跳转目标本身不要再依赖另一个跳转。
rel=canonical
canonical 是提示,不是指令。它能帮助蜘蛛理解你的偏好,但当它与站内链接、sitemap、301 给出的信号互相矛盾时,最终判断未必如你所愿。比较常见的自相矛盾是:多个重复地址的 HTML 里,canonical 都指向自己。
站内链接指向哪一个
内链是持续的投票。如果站内一半链接指 A、一半指 B,蜘蛛很可能两边都抓、两边都保留。想收敛,先从模板层的链接写法统一开始,这比事后加 canonical 更省事。
参数要不要留
判断标准可以简单一些:会影响页面正文的参数属于有效参数,通常需要保留,但要控制组合数量,避免筛选条件能被无限叠加;纯追踪类参数(utm 系列、渠道标识、会话 ID)尽量只出现在外部来源的链接上,站内链接和 sitemap 里不要带。真正麻烦的不是单个参数,而是参数能自由组合出的排列,蜘蛛很容易在这种页面上消耗掉大部分抓取量。
服务器层面的一致性
如果两种地址都返回 200 且内容完全一致,蜘蛛只能靠 canonical 去猜你的意图。更稳的做法是让其中一个明确返回 301。另外要确认不同地址返回的 HTML 是否一致,有些站点的移动版和桌面版 canonical 规则不同,容易互相指向对方。
可以按顺序做的自查
- 翻抓取日志,看同一个路径出现了几种写法,各自被访问了多少次。
- 检查站内链接是否统一:绝对路径还是相对路径,带不带尾斜杠。
- 检查 canonical 是否指向自身页面,而不是希望保留的目标地址。
- 检查 sitemap 里提交的是哪一种写法,是否和站内链接一致。
- 检查 301 是否指向最终地址,链路上有没有多余的中间跳转。
规范化做得好不好,一个直观的观察指标是:抓取日志里「内容相同但地址不同」的条目占比。这个比例长期偏高,说明站点还在把抓取量花在重复地址上。
URL 规范化不是一次性配置,而是链接写法、跳转规则、canonical 和 sitemap 四者长期保持一致的结果。任何一处先改动,另外三处跟不上,重复地址就会重新长出来。