判断一个页面是否被收录,大多数人先看内容,再看标签。但在爬虫眼里,页面的第一身份是 URL。同一个页面如果存在几种不同的 URL 写法,它就不是一个页面,而是几个待处理的地址。这些地址会各自排队、各自抓取,最后在索引里形成互相竞争的结果。
下面按几种最常见的写法差异,说说它们分别会带来什么问题,以及怎么查。
为什么同一页面会出现多个 URL
URL 的重复很少是故意造成的,多数来自几个日常动作:站内链接从不同位置生成时大小写没统一;导航里写的是带斜杠的目录形式,正文链接写的是不带斜杠的形式;分享链接被加上了追踪参数;后台切换过 CMS 或做了伪静态,旧写法仍然能访问。只要其中任何一种写法返回正常页面,它就有可能被单独抓取。
大小写:先确认服务器是否区分
是否区分大小写,取决于服务器和系统环境。Linux 上常见的 Nginx、Apache 默认区分大小写,/News 和 /news 是两个不同的地址;Windows 环境下的 IIS 通常不区分。同一个站如果换过服务器,情况还可能发生变化。
- 用两种写法分别访问,看是否都返回正常内容。
- 如果都返回 200 且内容相同,说明这两个地址都在对外供应同一个页面。
- 看页面里的 canonical 指向哪一个,确认自己声明的首选版本。
处理方式通常是二选一:要么让非首选写法 301 跳到首选写法,要么统一站内所有链接的写法,让另一种写法根本不出现在页面上。
结尾斜杠:目录形式和文件形式
带斜杠和不带斜杠往往被服务器当作两个地址。/about/ 和 /about 如果都能打开同一个页面,就等于对外提供了两个入口。常见做法是选一种作为首选,另一种用 301 跳过去。选哪一种不重要,重要的是站内链接、sitemap、canonical 三处的写法保持一致,不要一处带斜杠一处不带。
参数顺序与无用参数
参数类页面最容易产生写法分叉。参数的先后顺序不同,URL 字符串就不同,例如 ?type=1&page=2 和 ?page=2&type=1,服务器返回的内容完全一样,但爬虫看到的是两条地址。另外还有几类参数会持续制造新 URL:
- 来源追踪参数,如 utm_source、from、ref 之类。
- 会话或临时标识参数,如 sid、sessionid。
- 排序、筛选、每页数量等可自由组合的参数。
能去掉的就不要在站内链接里带上;必须保留的,可以通过 URL 参数工具或服务器规则做归一处理。不要仅靠 robots.txt 去挡,那只阻止抓取,不解决地址重复。
中文与特殊字符的编码
中文路径在传输时会被编码成 %E4%B8%AD 这样的形式。这里有一个容易被忽略的细节:十六进制字母的大小写不同,编码后的字符串也不同,%e4 和 %E4 在部分系统里被视作两个地址。如果站内不同位置生成的编码大小写不一致,同样可能分叉。更稳妥的做法是栏目和文章路径尽量使用英文或拼音,中文标题放在页面的标题和 H1 里。
URL 长度与层级
层级过深的 URL 通常意味着内链入口少,爬虫要到更深处才能发现页面,抓取频率也更容易变低。这不是说长 URL 一定不被收录,而是它往往和站内结构问题一起出现。把重要内容放在较浅的层级,比事后调整 URL 更省事。
可以按这个顺序自查
- 抽查一批页面,把站内指向它们的链接找出来,看是否存在大小写、斜杠不一致的情况。
- 对比 sitemap 里写的 URL 和页面 canonical 声明的 URL,两者应完全一致。
- 用抓取工具批量访问,记录所有返回 200 但内容相同的地址,归类整理。
- 对确认重复的地址,确定一个首选版本,其余用 301 指向它。
- 回到页面模板和编辑流程,从生成环节避免再次产生新写法。
URL 写法统一这件事,本质上不是为了让页面更快被收录,而是减少爬虫需要处理的重复地址,让抓取资源花在真正有内容的页面上。处理完之后索引状态会不会变化、多久变化,仍然取决于页面本身的质量和站点整体情况,没有固定的时间表。