做蜘蛛池的人常遇到一种情况:日志里抓取请求看着不少,但真正被索引的入口页并没有同步变多。追问下去,很多时候不是蜘蛛不来,而是同一个入口页在它眼里变成了好几个不同的 URL,抓取配额被摊薄了。这一篇只讲 URL 层面的重复,不涉及内容质量判断。
一个入口页怎么会变成多个地址
下面这些差异,在浏览器里访问几乎没感觉,但在蜘蛛的待抓队列里往往是彼此独立的一条:
- 协议与主机名:http 与 https、带 www 与不带 www、不同子域名(即使模板完全相同)。
- 路径大小写:/PageA 与 /pagea。Windows、IIS 环境常不区分,Linux、Nginx 默认区分。
- 结尾斜杠:/a 与 /a/。
- 默认文档:/a/ 与 /a/index.html。
- 查询参数:?id=1、?id=1&from=x、参数顺序颠倒。纯锚点(#后面部分)通常不产生新地址。
重复地址会带来什么
- 抓取配额被摊薄:原本能爬一百个位置的量,分给了三个互为镜像的地址。
- 日志统计失真:按路径去数“蜘蛛来过几次”,结果高估或低估都不奇怪。
- 信号分散:外链、内部链接分别指向不同版本时,蜘蛛收到的信息不统一。
- 维护成本上升:改一次入口页模板,要逐个确认几个地址是否同步生效。
把 URL 收紧的几条做法
- 先定一套规则并写下来:全站路径统一小写、统一结尾斜杠、只保留一个主机名、统一走 https。
- 内部链接用同一套写法。入口页之间的互链、列表页链接、sitemap 中的地址都按这套规则输出。
- 老地址用 301 归一到正式地址,不要留 302,也不要留多跳链条。
- 模板里输出 canonical,指向归一后的地址,和实际返回的内容保持一致。
- 参数能减就减。UTM、来源标记这类只用于统计的参数,不要写进站内链接。
- 需要保留参数的页面(分页、筛选),固定参数顺序,避免同一组参数出现多种排列。
- 在服务器层做重写,让 /a 直接跳到 /a/,而不是两份内容各自返回 200。
几个容易被忽略的例外
不是所有差异都该抹平。分页参数、筛选参数往往对应真实不同的内容列表,一刀切屏蔽或全部 301 到首页,反而让蜘蛛走不到深层页面。判断标准其实很简单:这两个地址返回的内容是否真的不同?内容相同就归一,内容不同就保留,并让它们互相可以被发现。
另外,不要在 robots.txt 里屏蔽重复地址来图省事。被屏蔽的 URL 蜘蛛通常不会抓取,也就看不到你设置的 301 或 canonical,归一动作等于白做。合理的顺序是:先让它能抓、能跟着跳,再完成归一。
URL 归一本身不产生新内容,它做的是别让有限的抓取配额浪费在镜像地址上。在入口页数量扩张之前,先把这套规则落到模板、站内链接和服务器配置里,比事后一个个去改要省事得多。