URL 里出现中文、空格或特殊符号,很多站点在浏览器里能正常打开,就默认这件事已经处理好了。但对抓取端来说,地址栏里显示的内容和实际发出的请求路径经常不是同一个字符串。编辑、开发、服务器和日志各看各的,收录问题往往从这里开始。
地址栏显示的不是请求路径
浏览器在地址栏里通常会把百分号编码还原成可读文字,比如把 %E4%B8%AD 显示成“中”。人复制粘贴时可能拿到中文形式,也可能拿到编码形式,取决于从哪里复制。但网络请求发出时,路径必须是编码后的形式。也就是说,同一个页面在人的眼里是一个地址,在日志里可能是另一个地址。
如果站点内部有的链接写中文、有的写编码、有的在 sitemap 里又换一种写法,抓取端就可能把同一个页面当成多个 URL 来发现和抓取。
中文 URL 的编码方式要统一
目前主流做法是使用 UTF-8 百分号编码,也就是一个中文字符编码成三个字节,每个字节前面加百分号,例如“中”对应 %E4%B8%AD。但一些较早的服务器或程序仍可能按 GBK 等方式解码,导致同一个中文路径在不同环境下被解析成不同结果。
更稳妥的策略是:URL 路径尽量使用 ASCII 字符,例如拼音或英文单词;如果业务上必须保留中文,则全站统一使用 UTF-8 编码,并且在内链、sitemap、canonical、重定向规则里保持同一种写法。
空格、加号与保留字符
空格在 URL 路径里应该编码成 %20,而不是加号。加号在查询参数里有时被解释为空格,但在路径中就是普通字符,两者混用容易出现路径对不上。
另外,& 在参数中如果不编码,会被解析成参数分隔符,后面的内容可能被截断。# 后面的片段不会发送给服务器,因此不要把重要参数放在井号后面。
- 空格:路径中统一用 %20,不要用 +。
- &:作为参数值出现时要编码成 %26,否则会被当成新的参数。
- #:片段仅浏览器使用,服务器和抓取端看不到。
- 保留字符:: / ? # [ ] @ ! $ & ' ( ) * + , ; = 在作为普通内容时需要编码。
编码不一致会带来哪些收录问题
最常见的不是“收录不了”,而是同一页面出现多个 URL,导致抓取次数被分散。具体表现包括:
- 同一篇文章同时存在中文路径和百分号编码路径,两个都被抓取。
- 百分号编码里字母大小写不同,例如 %e4 与 %E4,有些服务器视为不同路径。
- canonical 指向的是中文形式,而实际可访问的是编码形式,规范信号变弱。
- 服务器解码失败,返回 400 或 404,抓取端反复尝试。
- sitemap 里写一种形式,内链里写另一种形式,日志里又出现第三种。
这些问题单独看都不大,但会在日志里表现为抓取次数增加、有效页面发现变慢,排查时也容易误判。
自查与处理顺序
发现 URL 编码相关的问题后,可以按下面的顺序处理,先统一再收口。
- 确定规范形式。优先选择 ASCII 路径;必须用中文时,统一为 UTF-8 百分号编码,并明确大小写规则。
- 检查服务器。用编码后的 URL 直接访问,确认返回 200,而不是 404、400 或跳转到另一个编码形式。
- 统一站内写法。内链、导航、面包屑、sitemap、canonical 全部使用规范形式,不要混用中文和编码。
- 查看服务器日志。搜索 % 开头的编码片段,看是否出现同一路径的多种编码形式,以及是否被反复抓取。
- 对已有多个形式的 URL 做处理。保留一个规范版本返回 200,其余用 301 指向它,或者用 canonical 明确主版本。
- 检查参数编码。中文、空格、& 出现在参数值时,确认它们被正确编码,避免参数被截断或产生不同 URL。
参数中的中文和特殊字符
筛选、搜索、排序参数里带中文的情况很常见。这里要注意两点:一是同一个参数值不要出现多种编码形式;二是不要因为编码差异产生大量只有参数值不同的 URL。对于这类页面,可以结合参数处理规则,决定是否允许抓取、是否用 canonical 指向主版本,或者用 robots.txt 屏蔽无价值组合。
URL 编码本身不是收录的开关,但它决定了抓取端、服务器和日志看到的是不是同一个地址。地址对不上,后面的质量判断和收录判断都会受到干扰。
如果站点规模较大,可以先把编码形式统一,再观察日志中重复路径和抓取分布的变化。不要指望改完编码就立刻提升收录,它更多是减少无谓的抓取消耗,让真正需要被发现的页面更容易被稳定访问。