浏览器能打开,抓取端拿到的却不一定是同一个地址
在地址栏里输入带中文的链接,浏览器会自动把中文转成 %E4%B8%AD 这样的百分号编码再发出去。你看着地址栏里还是中文,复制出来却可能是一长串编码。同一份内容,就这样有了两种甚至更多种写法。抓取端不认“看起来一样”,它按字符串比对 URL,写法不同就是不同的地址。
这不会直接导致页面不被收录,但会让抓取和判断变得模糊:本该花在一个地址上的抓取量被分走,页面之间的信号也被拆散。
容易出问题的几类字符
- 空格:会被编码成 %20,有时又被写成 +,在部分服务端上两者含义并不相同。
- 中文和中文标点:逗号、顿号、括号编码后都很长,人工核对时极易看错一位。
- # 和 ?:# 后面的内容浏览器不会发给服务器,? 后面则常被当作参数处理。
- 大小写:路径部分通常区分大小写,Admin 和 admin 是两个地址。
- &:在参数里是分隔符,出现在路径正文里需要写成 %26。
一个页面变成多个 URL 的常见过程
典型情况是:栏目页里的内链用的是原始中文,sitemap 导出的是编码后的形式,外部合作方复制过去的又是第三种写法。三种写法都返回 200,内容一模一样,抓取端会把它们当三个页面分别抓取、分别判断。
还有一种更隐蔽的情况:服务端对编码形式的处理不一致。访问 /tag/搜索引擎 和 /tag/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E 得到的结果不一样,一个正常显示,一个 404 或跳回首页,但两个页面里的 canonical 又都指向同一个地址。
服务端应该怎么接
先确认服务器能正确解码两种写法,让它们指向同一份内容,并且只保留一个正式地址。做法通常是把非正式写法 301 到正式写法,注意只跳一次,不要 A 跳 B、B 又跳 C。重定向链越长,抓取端越容易在中间停下。
现在可以做的几件事
- 确定一个正式写法:要么全程用编码形式,要么全程用原始中文,不要混着来。
- 把内链、canonical、sitemap、分页链接的写法统一成正式写法,逐处核对。
- 翻日志看同一内容是否被多种写法反复抓取,这类重复抓取会占掉不少抓取量。
- 新做的页面尽量用短、纯 ASCII 的路径,比如拼音或英文单词,后续维护成本最低。
- 已经上线很久、只有一种写法的中文 URL,不必为了“规范”全部重做,改动带来的迁移成本往往更大。
已经存在多种写法时,优先处理哪一类
先处理被内链反复指向、或者已经出现在索引里的那些变体。处理方式是页面上放 canonical,服务端同时做 301,两条一起用更稳。只在页面上写 canonical 而服务端仍返回 200,抓取端大概率会把两个地址都抓一遍。
怎么确认自己站上有没有这个问题
用 site: 加编码后的路径查一下,看索引里出现的是哪一种形式;再取一段时间的服务器日志,按路径统计重复出现的编码变体。如果同一篇内容在日志里以两三种写法被高频抓取,基本可以确认存在 URL 不一致,处理的价值也就比较明确。
URL 写法本身不复杂,麻烦的是它会在内链、sitemap、外链、日志里各写各的。统一一次,后面省下来的核对成本比想象中多。