hreflang互指对不上,多半是另一边先改的
本文目录
- 你写的那一半对了,另一半算数吗?
- 它是少数几个必须双向成立的声明
- 翻倍还只是最好的情况
- 算一笔账:一个成员掉队,损失面有多大
- 这次怎么查的
- 这次没算进去的几件事
- 73个站的集群到底有多大、跨得有多远?
- 规模:中位数15条,最大259条
- 默认版本:87.7%的站声明了
- 条数最少的那批站,未必是做得差
- 跨域:277条指向别人的域名
- 最有意思的一条跨到了别的公司
- 顺手说一句:跨域这件事本身没错
- 语言代码本身写错的不多
- 抓到的240个目标页里,有多少真的把你列了进去?
- 两侧完全一致的有87.9%,对不上的12.1%
- 自指:95.0%的目标页把自己列了进去
- 站级看,五分之一的站有问题
- 出问题的站各有各的形态
- 那6个没有任何声明的页面,值得单独想一想
- 非200的那18条,有几条是真的坏了?
- 为什么要换个身份再抓一遍
- 7条立刻变成正常
- 剩下那11条是真问题,而且形态很说明问题
- 地区限制这一类要单独想清楚
- 把这11条按责任方分个类
- 同一个地址在两边被标成不同的语言,占多少?
- 8894次比对里,1758次标法不同
- 绝大多数争的是同一件事:谁该当默认版本
- 为什么这一处最容易吵
- 另一组更像是整体平移出了错
- 标法不一致到底要不要紧
- 怎么把默认版本这件事一次定死
- 声明的地址和最终落地的地址是同一个吗?
- 240个正常打开的目标里,32个跳到了别处
- 为什么跳转在这件事上格外要命
- 常见的三种跳转成因
- 本文的处理办法
- 跨域那277条,另一头到底在谁手里?
- 21个站,124个外部主机
- 按另一头归谁管,可以分成三档
- 124个外部主机里,顶级域的分布很说明问题
- 一个负结果:跨域不等于跨平台
- 集群大小不对称的三个例子
- 把这套关系挪到清单文件里,是不是更省事
- 为什么这套声明比别的声明更容易坏?
- 它的正确性不由你单独决定
- 更新这件事没有触发点
- 坏了之后没有任何报错
- 跟另外两类失效的区别
- 还有一个常被忽略的相互作用
- 出问题的时候,怎么判断该找谁?
- 四个问题,顺序不能乱
- 三种典型局面与对应的动作
- 找对面团队的时候,带上这三样
- 一份可以直接抄的沟通结构
- 推不动的时候怎么办
- 自己站上怎么查,查完按什么顺序修?
- 五步核对
- 修的优先级
- 把核对做成例行的三个触发点
- 还有一个偷懒但有效的办法
- 把核对写成一段脚本,逻辑就这几步
- 常见问题解答
- 只有我这边写了,对方没写,能生效吗?
- 怎么快速判断我的站有没有这个问题?
- 目标地址打不开,一定是对方的问题吗?
- 同一个地址被两边标成不同语言,要紧吗?
- 声明的地址会跳转,需要改吗?
- 跨域声明是不是应该避免?
- 集群太大维护不动,有什么办法?
- 对面团队推不动怎么办?
- 权威参考资料
摘要:从73个多语言站的首页抓出2529条语言版本声明,再顺着这些声明实抓258个目标页,逐个检查对面有没有把你列回来。240个能打开的目标页里,211个两侧集群完全一致,站级口径下14个站(19.2%)至少有一个成员对不上。更值得看的是另外两个数:同一个地址在两侧被标成不同语言代码的比例高达19.8%,绝大多数集中在谁该当默认版本这一件事上;18条打不开的目标里换个浏览器身份重抓,7条立刻变成正常。文中给出跨域集群的规模、跳转造成的错位与按责任方划分的修复顺序。
八月十九日有一组数据在圈子里传得挺快:某个大型论坛站在某AI搜索里的引用份额,从3.83%掉到0.52%,跌了86.4%。有人把原因归到八月八日那次检索方式变更上,但仔细对一下时间线这个解释并不成立——变更发生在八日,份额是十四日之后才塌下去的。
这件事里最让人不舒服的不是掉了多少,而是掉的原因在别人家里,而对方没有义务告诉你。你能做的只有事后拿数据反推,还未必推得对。
网站上有一类声明天生就是这个处境:它的正确性不取决于你自己写得对不对,取决于另一个页面怎么写。那个页面可能归另一个国家的团队,可能归一家代理商,甚至可能压根不是你公司的资产。
语言版本声明就是最典型的一个。保哥把这批多语言站的首页拉下来,顺着它们声明的每一条链路往对面走,看看对面认不认这门亲戚。
你写的那一半对了,另一半算数吗?
先把规矩说清楚。这套声明的核心要求不是你指对了人,而是同一组语言版本里的每一个页面,都必须列出完全相同的一整套地址,并且要把自己也列进去。
它是少数几个必须双向成立的声明
网页上大多数声明是单向的:你写规范网址,你写索引指令,你写修改时间,写完就生效,跟别的页面没关系。
语言版本声明不一样。你在中文页上写英文版在那儿,英文页上必须也写中文版在这儿。少了任何一边,搜索引擎都不会把这两个页面认成一组——它没法确认这门亲戚是不是你单方面攀的。
这个设计有它的道理:如果单向就算数,任何人都可以在自己站上声明你是他的某语言版本,然后蹭走一部分流量。双向要求把这条路堵死了,代价是维护成本翻倍。
翻倍还只是最好的情况
实际成本远不止翻倍。一个站有12个语言版本,那就是12个页面每个都要列出完整的12条。新加一门语言,要改的不是1个页面,是13个。
如果这12个版本跑在同一套模板上,改起来还算容易;如果它们分属不同的市场团队、不同的建站系统、甚至不同的域名,这件事就变成了一次跨组织协作。
算一笔账:一个成员掉队,损失面有多大
把这件事量化一下会更有体感。假设一个站有8个语言版本,每个版本有5000个页面,也就是4万个页面组成8000组关系。
现在其中一个语言版本的模板漏了自指。后果不是那5000个页面出问题,而是全部8000组关系里,每一组都少了一个成员——剩下7个版本之间的关系仍然成立,但它们跟那一个版本之间的定向全部作废。
换个更糟的情形:漏的不是自指,而是那个版本的模板压根没输出这套声明。这时候它自己的5000个页面完全脱离集群,其他7个版本指着它的那8000条声明也全部变成单向,等于白写。
这就是为什么这件事值得单独查一遍:一个模板文件里的一行,能一次性废掉整个站的语言定向。而它出错时页面照常打开,任何常规监控都不会响。
这次怎么查的
数据抓于2026年8月21日,样本是168个海外品牌独立站的首页,其中73个站写了语言版本声明。做法分三步。第一步,从这73个站的首页里把所有语言版本声明抽出来,一共2529条。第二步,每个站挑4条目标地址,实际抓一遍,一共258个页面。第三步,解析目标页自己的声明,跟源页那一套做集合比对。
比对的判据严格按规范来:两侧列出的地址集合应该完全相同,且各自都包含自己。差一条就算对不上。
这次没算进去的几件事
三类情况被排除在外。
一是只在首页上做的抽查。一个站的语言关系是逐页成立的,首页对得上不代表商品页也对得上;反过来也一样。所以文中的站级出错率是下限,真实情况只会更高。
二是写在清单文件里的那种表达方式。规范允许把同样的关系写进站点地图,这次只解析了页面上的写法。有些站两种都用,也有些站只用后一种——后者在本文的口径里会被记成没写,这一点要打个折扣看。
三是响应头里的写法。它同样合法,但实际使用极少,这批样本里一条都没遇到。
还有一层边界要交代清楚:这类声明的正确性会随对面团队的每一次改版而变,所以本文的每个数字都只对2026年8月21日那一刻成立。这不是免责声明,而是这件事的性质决定的——出错在这里是单向累积的,没有任何机制会把它自动修回来。同一批站半年后再抓一遍,站级出错率只会比19.2%更高,除非中间有人专门去核对过。这也是为什么下文把核对挂在触发点上,而不是建议你每季度跑一次。
73个站的集群到底有多大、跨得有多远?
先看静态的那一面,也就是这些站自己写了些什么。
规模:中位数15条,最大259条
73个站一共写了2529条声明,每站中位数15条,最大的一个站写了259条。写得多的几个站分别是259、236、202、190、116、112、110条。
259条意味着什么?意味着这个站有两百多个语言地区组合,而每一个组合对应的页面上,都得原样再写一遍这259条。整个集群的维护面是259乘259。
默认版本:87.7%的站声明了
这套声明里有一个特殊值,用来指定当用户的语言不在你的列表里时该去哪儿。73个站里64个写了它,占87.7%。
这个覆盖率算高的。但后面会看到,恰恰是这个特殊值成了两侧最容易吵架的地方。
条数最少的那批站,未必是做得差
73个站的中位数是15条,但分布很偏:有一批站只写了两三条。
看下去会发现这批站多数是双语站——英语加一门本地语言,或者英语加中文。它们的集群小,维护面自然也小,出错的机会跟着变少。
这一点值得给正在扩语言的团队提个醒:每加一门语言,维护面不是线性增长而是平方增长。三门语言是9条关系,十门语言就是100条。决定加不加一个市场时,这笔维护成本很少被算进去,而它是要一直付的。
跨域:277条指向别人的域名
2529条里有277条指向的不是本站的域名,占11.0%,涉及21个站,一共124个不同的外部主机。
形态分几种。最常见的是国别域名矩阵:主站在通用域上,各个市场用各自国家的域名,比如同一个鞋类品牌指向新西兰、澳大利亚、英国、韩国、科威特五个国别域。
其次是中国单独一套:有的品牌把中国站放在另一个域名下,从主站指过去。样本里有几个都是这个形态。
最有意思的一条跨到了别的公司
那个鞋类品牌的日语版本,指向的域名既不是它的主域,也不是它的国别域,而是一家日本本地公司的域名——那是它在日本市场的经营方。
这一条把本文的主题摊得非常清楚:这个页面上的声明能不能长期成立,取决于另一家公司的网站怎么改。他们换个建站系统、调一次地址结构、或者干脆终止合作,你这边不会收到任何通知。
顺手说一句:跨域这件事本身没错
容易把跨域读成不规范,其实规范里明确允许。真实世界的多语言站有大量正当理由要用不同域名——商标在某些国家归别人所有,某些市场必须用本地域名才有信任度,某些国家的支付通道只认本地主体。
真正决定难度的不是域名,是那一头归谁管。同一个团队维护五个国别域,改起来跟改一个站没区别;不同公司各管一头,哪怕只有两个域也很难同步。看域名判断风险会看错,要看的是组织边界。
语言代码本身写错的不多
顺手也查了代码写法。明显不合规的只有七条:把国家码当语言码用的两条,把语言写成不存在的两字母的一条,还有几条把语言和地区写反或者重复。
这里要坦白一个自己的口径问题:第一版校验把中文的繁简写法判成了不合规,因为我的规则只认两位国家码,没考虑到语言标签规范里语言与地区之间还能插一层文字子标签。这类误报的成因是校验规则比规范本身更窄,属于写检查脚本时最常见的一种错。修正之后,真正的代码错误就剩那七条。
抓到的240个目标页里,有多少真的把你列了进去?
这是本文的核心实验。258个目标地址实抓下来,240个正常打开,逐个解析它们自己的声明再跟源头比对。
两侧完全一致的有87.9%,对不上的12.1%
240个目标页里,6个页面一条语言版本声明都没有,占2.5%。剩下234个有声明的,211个(90.2%)的集合与源页完全相同。以240为分母算,完全一致的是87.9%。
集合重合度的分布是这样的:
| 两侧集群的重合度 | 页面数 | 占比 |
|---|---|---|
| 完全相同 | 211 | 90.2% |
| 九成以上但不完全一样 | 8 | 3.4% |
| 五成到九成 | 13 | 5.6% |
| 一成到五成 | 1 | 0.4% |
| 不到一成 | 1 | 0.4% |
重合度中位数是100%,四分之一分位也是100%。最低的一个只有1.2%——那意味着两侧几乎在说两件不相干的事。
自指:95.0%的目标页把自己列了进去
规范要求每个成员都要包含自己。240个目标页里228个做到了,占95.0%。剩下12个漏了自己,涉及少数几个站。
漏掉自指的后果比想象中大:搜索引擎会认为这个页面不属于任何一组,于是它跟其他语言版本之间的关系全部作废,哪怕别人都指着它。
站级看,五分之一的站有问题
把页面级结果收到站级:73个站里14个至少有一个成员对不上,占19.2%。
这个口径比页面级更有意义。原因是一组语言版本是共同体,只要其中一个页面掉队,那一整组的关系在搜索引擎那边就不完整。页面级的87.9%听着还行,翻译成站级就是每五个做多语言的站里有一个,某些页面上的语言关系根本没生效。
出问题的站各有各的形态
| 问题形态 | 典型站数 | 说明 |
|---|---|---|
| 目标页集群与源页不一致 | 9个站 | 两边列的地址不是同一套 |
| 目标页没把自己列进去 | 3个站 | 缺自指,整组关系作废 |
| 目标页一条声明都没有 | 4个站 | 对面根本没参与这套机制 |
最整齐的一个例子是某家居品牌:抓到的4个目标页全部一条声明都没有。这不是漏写,更像是那几个国家的站点由完全独立的系统在跑,压根不知道主站在指着它们。
那6个没有任何声明的页面,值得单独想一想
集群对不上还算有救——两边都参与了这套机制,只是内容有出入。目标页一条声明都没有是另一种情况:对面根本没上这条船。
这6个页面里4个来自同一个家居零售巨头,剩下两个分别来自一个服装品牌和一个小站。前者的形态最值得注意:主站的清单里认认真真列了几十个国家,而被列进去的那几个国家站,页面上干干净净什么都没有。
合理的推测是这些市场站建站更早、或者由本地团队独立采购的系统,从来没有接入过总部这套国际化配置。主站那边加清单时只需要在自己的模板里填地址,不需要对面配合,所以这件事可以做完一半就上线。
这也解释了为什么这类问题能长期存在:做一半也能上线,而上线之后没有任何东西会告诉你另一半没做。
非200的那18条,有几条是真的坏了?
258个目标里有18条没能正常打开。这个数字不能直接当失败率用,必须先做一步。
为什么要换个身份再抓一遍
跨站抓取有一条铁规矩:一次失败可能说的是这个地址坏了,也可能说的是这台机器不受欢迎。这两件事的处置方式完全不同,混在一起报会得出错误的结论。
所以那18条全部换成普通浏览器身份重抓了一次。
7条立刻变成正常
结果是18条里7条换个身份就打开了,占38.9%。其中某个家电品牌的3个欧洲语言页面,某个户外品牌的4个欧洲页面,全部属于这一类。
还有1条反过来,原本返回拒绝的换了身份变成完全连不上——这类抖动在跨境链路上很常见。
不做这一步,这份报告里的失败率会写成7.0%;做完之后是4.3%。虚高了六成。
剩下那11条是真问题,而且形态很说明问题
剩下的11条里,最值得说的是三条来自同一个珠宝品牌:它的欧洲站把保加利亚、爱沙尼亚、拉脱维亚三个市场的英语版本,指向了自己的中国站域名。而那个中国站上,这三个地区页面全部返回未找到。
这一条几乎是本文主题的标本:声明写在欧洲团队的模板里,被指的页面归中国团队管,而中国团队做地区页面调整时,不会有任何机制去通知欧洲团队。
另外两条来自一个服装品牌:它声明了香港和俄罗斯两个版本,前者返回未找到,后者返回服务不可用。俄罗斯那条尤其典型——那是一个几年前就退出的市场,页面早就不提供服务了,而首页上的声明还在。
还有三条来自一个美妆零售站,它的罗马尼亚、法国、芬兰版本对两种身份都返回拒绝,看起来是地区级的访问限制。这类严格说不算坏,只是从我这个位置进不去。
地区限制这一类要单独想清楚
访问限制看起来是最无害的一类:真实用户在当地能打开,只是我这台在境内的机器进不去。但它有一层容易被忽略的影响。
搜索引擎的抓取程序也不是从各国均匀发起请求的,它的出口位置相对集中。如果一个页面对大部分位置都不接待,那么它被抓到、被理解、被纳入语言关系的机会就会下降。
所以这一类的处置不是修声明,而是回去问一句:这个访问限制策略是有意为之,还是防护规则误伤?这两种情况的答案完全不同,而多数团队从没被问过这个问题。
把这11条按责任方分个类
| 形态 | 条数 | 该找谁 |
|---|---|---|
| 被指的页面确实没了 | 4 | 对面团队,或者把这条声明删掉 |
| 市场已退出但声明还在 | 1 | 自己,属于收尾没做完 |
| 地区级访问限制 | 3 | 不用管,但要知道搜索引擎那边也可能进不去 |
| 限流或网络抖动 | 2 | 换个时间再验一次 |
| 连不上 | 1 | 同上 |
同一个地址在两边被标成不同的语言,占多少?
集合比对只回答了地址对不对得上,还有一个更细的问题:同一个地址在两侧被贴的标签是不是同一个。
8894次比对里,1758次标法不同
做法是把两侧共同拥有的每一个地址挑出来,看它在源页和目标页上各被标成了什么。一共比了8894次,其中1758次标法不同,占19.8%。
这个比例远高于集合对不上的比例。也就是说,两侧列的地址往往是同一套,但对每个地址是什么语言的理解并不一致。
绝大多数争的是同一件事:谁该当默认版本
把这1758次按标法组合排个序,头部几组是这样的:
| 源页标法 → 目标页标法 | 次数 |
|---|---|
| 默认版本 → 美式英语 | 43 |
| 通用英语 → 默认版本 | 40 |
| 美式英语 → 默认版本 | 31 |
| 默认版本 → 通用英语 | 17 |
| 默认版本 → 英式英语 | 9 |
| 奥地利德语 → 德国德语 | 8 |
前五组全部围绕同一个地址:那个既是英语版又被当成默认落点的页面。源页说它是默认版本,目标页说它是某个具体的英语;或者反过来。
为什么这一处最容易吵
因为默认版本这个值在语义上是特殊的:它不描述这个页面是什么语言,它描述的是当没有更好的匹配时该去哪儿。这是一个关于整组的决策,不是关于单个页面的属性。
一个页面可以既是美式英语版,又同时是整组的默认落点,规范也允许同一个地址被写两条声明来同时表达这两件事。问题在于,很多站只写了其中一条,而写哪一条取决于当初是谁在改这个模板。
英文站的人觉得它就是英语版;负责国际化的人觉得它是兜底页。两边都不算错,凑到一起就对不上。
另一组更像是整体平移出了错
还有一组很整齐的:某个站的波兰英语版,在目标页上分别被标成了比利时英语、希腊英语、法国英语、立陶宛英语、葡萄牙英语,各4次。这些地区码本身全部合法,都能在官方的语言子标签登记表里查到,所以任何语法检查都不会报错。
这个形态不像人手写错,更像模板在渲染时把地区变量取错了——每个国家的页面都把这条声明贴上了自己所在国家的地区码。一处模板逻辑的偏差,会在整组里复制出几十条错误声明。
标法不一致到底要不要紧
要紧程度介于中间。搜索引擎在处理这类冲突时通常会取更保守的解释,也就是把有分歧的那条声明忽略掉,其余的照常生效。所以后果不是整组失效,而是有分歧的那个语言版本失去了定向。
但默认版本那一处是例外。如果整组都说不清谁是兜底,那么当用户的语言不在列表里时,搜索引擎只能自己挑一个——而它挑的往往不是你想要的那个市场。
怎么把默认版本这件事一次定死
内部先回答三个问题,答完就不会再吵。
第一,如果一个用户的语言和地区都不在你的清单里,你希望他看到哪个页面?多数品牌的答案是英语总站,少数会选主力市场的站。
第二,那个页面本身是不是也代表一个具体的语言地区?如果是,就要写两条声明——一条说它是某语言版本,一条说它是整组的兜底。这两条并不冲突,规范允许。
第三,这个决定怎么传达给所有市场团队?口头说没用,最好是写进那份共用的模板变量或者配置文件里,让各站取同一个值。
第三问答不上来,前两问答得再清楚也会在半年内重新走样。
声明的地址和最终落地的地址是同一个吗?
还有一层错位不在声明里,在链路上。你写的地址能打开,但打开之后已经不是它了。
240个正常打开的目标里,32个跳到了别处
把最终落地地址跟声明地址逐条比,32条不一样,占13.3%,涉及12个站。多数站是4条全中——说明这是站点级的跳转规则,不是个别页面的问题。
为什么跳转在这件事上格外要命
假设你在中文页上声明德语版在某个地址,而那个地址会把访客跳到另一个地址。那么搜索引擎抓到的是跳转后的页面,而跳转后的页面上列的是它自己那一套地址——里面很可能没有你声明的那个原地址。
结果就是:你指的那个门牌号有人住,但住的人说自己不认识你。这一类错位在集合比对里会表现成两侧对不上,但根因不在任何一侧的声明,在中间那道跳转。
常见的三种跳转成因
第一种是地区探测跳转:站点按访客的网络位置自动分流。这类跳转对搜索引擎特别不友好,因为抓取程序的位置通常在少数几个地方,它永远只能看到其中一个版本。
第二种是地址结构改版遗留:语言目录从一种写法换成另一种,老地址做了跳转,而声明里还写着老地址。
第三种是尾斜杠、大小写、参数这类归一化跳转。这类无害,但会让机械比对报出一堆假问题——所以做比对时必须先做地址归一化,否则你会看到一份全是噪声的报告。
本文的处理办法
这次比对前先做了归一化:统一去掉协议、统一去掉开头的通用子域、去掉尾斜杠、去掉锚点和查询参数、统一转小写。做完这一步之后剩下的32条,是真的跳到了不同路径上。
跨域那277条,另一头到底在谁手里?
跨域是本文主题最直白的形态:声明的另一头写着别人的域名。这一节把这277条拆开看。
21个站,124个外部主机
写了跨域声明的站有21个,占73个站的28.8%。它们一共指向124个不同的外部主机。
规模最大的几个:某家居零售巨头指向六个以上国别域,某北欧礼品连锁指向阿联酋、印尼、韩国、科威特、土耳其五个市场的独立域,某鞋类品牌指向六个国别域外加一个代理商域。
按另一头归谁管,可以分成三档
| 档位 | 形态 | 能不能推得动 |
|---|---|---|
| 同一个团队的不同域 | 国别域名矩阵,同一套模板 | 能,改一次模板全部生效 |
| 同一家公司的不同团队 | 中国站、日本站单独一套系统 | 难,要走跨部门流程 |
| 不同的公司 | 代理商、合资方经营的市场站 | 很难,要走商务沟通 |
样本里三档都有。前面提到的那个日语版指向本地经营方的例子属于第三档,而那三条指向中国站却打不开的属于第二档。
124个外部主机里,顶级域的分布很说明问题
把这124个主机按顶级域归类,能看出这些站的国际化策略。
数量最多的是国家顶级域,覆盖从北欧到东南亚到中东的几十个市场。第二类是在通用域上开的地区子域,比如某电商平台给德语区、法语区各开一个。第三类最少,也最有意思:跟主站毫无字面关系的独立品牌域,也就是代理商或者合资方那种。
这个分布对应着三种截然不同的维护难度,而它们在页面源码上长得一模一样——都是一行声明,看不出背后隔着几个组织。
所以做审计时最好先做一件事:把所有跨域目标按注册主体归个类,标上归谁管。这份归类表做一次能用很久,也是后面所有沟通的底稿。
一个负结果:跨域不等于跨平台
本来预期跨域声明的另一头会跑在完全不同的技术栈上,那样问题会更严重。实际测下来不是这样。
把39个能拿到响应头的跨域目标跟源站首页做平台指纹对照,39个全部与源站相同,一个例外都没有。
这说明多数国别域只是同一套系统的不同门牌,技术上是通的。所以真正的障碍不是技术,是组织——同一套系统,两个团队,各自有各自的发布节奏。
集群大小不对称的三个例子
还有一类信号能直接看出两侧脱节:两边列的条数根本不一样。
某鞋类品牌源页列了86条,目标页只列71条,少了15条;某平台源页66条、目标页71条,反而多了5条;最悬殊的一个是源页列了35条,目标页只列3条。
差5条可能是时间差——一边刚加了新市场,另一边还没同步。差32条就不是时间差了,那是两边压根用的不是同一套清单。
把这套关系挪到清单文件里,是不是更省事
规范提供了第二种表达方式:把语言版本关系写进站点地图,每个地址下面挂上它的所有兄弟版本,跟写在页面上的效果等价。清单文件本身的结构与扩展方式决定了这种写法必须由程序生成,手写基本不现实。
这个方案在大集群上有明显优势。站点地图由程序生成,每次导出都会重新算一遍,天然带一个触发点;而模板里那几行是静态的,除非有人主动去改,否则永远不变。前面几节量出来的那些问题,本质上都来自后者的这个特性。
它的代价有三条。一是可读性差,出问题时不能靠打开页面源码看一眼就定位;二是排查工具支持不如页面写法普遍;三是它只解决你自己那一半的维护问题,对面不列你,写在哪儿都不成立。
务实的组合是:自己这边用清单文件生成,同时保留页面上的写法做冗余,两边由同一个数据源产出。这样既有触发点,又不损失可排查性。
为什么这套声明比别的声明更容易坏?
把前面几节的数字放到一起,能看出一条共同的线索。这一节把它说清楚。
它的正确性不由你单独决定
规范网址、索引指令、修改时间、资源提示,这些声明有一个共同点:写在你的页面上,由你的系统生成,正确与否你自己说了算。它们会失效,但失效的原因通常在你这边。
语言版本声明是另一类。你把自己那一半写得完美无缺,只要对面那个页面没把你列回来,这一组关系就不成立。你能控制的是必要条件,充分条件在别人手里。
更新这件事没有触发点
再看它什么时候该改。新增一个市场、下线一个市场、某个国家站换地址结构、某个页面被合并——这四件事发生时,整组所有页面的声明都应该跟着改。
问题是这四件事都不发生在维护声明的那个人手里。新增市场是业务决策,下线市场是财务决策,换地址结构是那个国家团队的技术决策。没有任何一件会自动变成一张改声明的工单。
那三条指向中国站却打不开的声明,就是这样来的:中国团队调整了地区页面,这个动作在他们那边是完全正常的一次改版,没有任何理由去通知欧洲团队。
坏了之后没有任何报错
第三个条件是失效完全静默。页面照常打开,用户照常购物,后台不会亮红灯。唯一的表现是搜索引擎在某个市场把错的那个语言版本排了上去,而这件事很难被归因到具体某一条声明。
三个条件凑齐——正确性依赖外部、更新没有触发点、失效没有报错——这套声明的长期状态几乎注定是慢慢烂掉。样本里19.2%的站级出错率,还是在只抽查首页的情况下量出来的。
跟另外两类失效的区别
| 类型 | 失效原因 | 能不能自己修 |
|---|---|---|
| 字段接错了触发源 | 该跟内容走,实际跟生成程序走 | 能,改自己的导出逻辑 |
| 压根没有触发源 | 写进模板之后再没人碰 | 能,加一道自动检查 |
| 触发源在别人手里 | 对方改了不通知你 | 不能,只能自己去查 |
前两类的解法都是往自己的流程里加东西。第三类不行——你没法在别人的发布流程里加检查点,只能在自己这边加一道定期核对。
还有一个常被忽略的相互作用
这套声明跟规范网址那一套是有交互的,而且交互的方式经常出人意料。
规则是这样:如果一个页面的规范网址指向别的地址,那么它的语言版本声明会被连带处理到那个地址上。所以当某个语言版本的规范网址被误设成英语版时,等于告诉搜索引擎这两个页面是同一个东西——语言关系当场作废。
这类错在做多语言站的时候相当常见,成因通常是模板里的规范网址取了一个全局变量,而那个变量在所有语言版本上都指向主站。判断办法很简单:打开任意一个非英语版本,看它的规范网址是不是指向自己。不指向自己,后面所有的语言版本工作都白做。
出问题的时候,怎么判断该找谁?
发现对不上之后,第一件事不是改,是分清这是谁的活。改错方向会白花很多力气。
四个问题,顺序不能乱
第一问:我这边列的那一套,自己站内的所有页面是不是一致的?先把自己那一半查干净,不然后面全是噪声。
第二问:对面那个地址能不能打开?打不开就先解决存活问题,比对集合没有意义。注意要换两种身份各试一次。
第三问:对面打开之后有没有跳转?有跳转就先看跳转的终点,不要拿声明地址去比。
第四问:终点页面上有没有列回来?没有列回来,才是真正要去找对面团队的那种问题。
三种典型局面与对应的动作
| 局面 | 根因在哪 | 该做什么 |
|---|---|---|
| 对面页面不存在 | 对方删过或改过地址 | 先确认那个市场还在不在,不在就删掉这条声明 |
| 对面能开但不列你 | 对方模板里没有这一条 | 拿具体地址找对面团队,别泛泛地说要加声明 |
| 对面列了但标法不同 | 两边对默认版本的理解不一致 | 先在内部把谁是兜底页定下来,再同步给所有市场 |
找对面团队的时候,带上这三样
跨团队推这类事最容易卡在对方不理解影响。经验是别讲原理,直接给三样东西:出问题的具体地址清单、他们那边应该加的那几行代码原文、以及这件事对他们自己市场的影响。
最后一样最关键。这套声明的收益是双向的——对面不列你,他们那个市场的页面同样拿不到你这边的定向。把这句话说清楚,比讲十遍规范有用。
一份可以直接抄的沟通结构
写给对面团队的那封邮件,四段就够。
第一段说现象:我们站上有N个页面声明贵站的某某地址是它的某语言版本,实测那些页面上没有指回来的声明。附一份不超过十行的地址对照表。
第二段说影响:这会导致我们两边的页面在搜索里互相抢同一批用户,你们那个市场拿到的可能是我们的英文页。
第三段说动作:需要在你们的页面头部加这几行,代码原文附上,位置在哪里也写清楚。
第四段说验证:改完之后告诉我们,我们这边抓一次确认。
关键是第三段要给到可以直接粘贴的东西。对面团队多半不熟悉这套机制,让他们自己去查规范,这件事就会一直排在待办的最后一行。
推不动的时候怎么办
如果对面短期内改不了,务实的做法是先把自己这边的那一条删掉。
理由是单向声明不生效,留着不但没用,还会在你自己的审计报告里持续报错,消耗每次核对的注意力。等对面能配合了再一起加回来。
需要说清楚的是,删掉不等于放弃那个市场——它只是不再声称这两个页面是一组。那个页面照常被收录、照常排名,只是少了一层定向。
自己站上怎么查,查完按什么顺序修?
这一节给可执行的顺序。整套流程不需要付费工具。
五步核对
第一步,从自己站上抽一批代表页面——首页、一个分类页、一个商品页、一个帮助中心页各一个,把它们的声明抽出来。
第二步,检查自指。每个页面的清单里必须有它自己。这一步最快,也最容易一次抓到问题。
第三步,检查站内一致性。同一组的几个页面列的应该是同一套,条数先对一下,条数不等就直接是问题。
第四步,实抓所有目标地址。记状态码,记最终落地地址,非正常的换个身份再抓一次。
第五步,解析目标页的声明,跟源页做集合比对,同时比每个地址的标法。
修的优先级
| 顺序 | 修什么 | 为什么排这里 |
|---|---|---|
| 1 | 缺自指 | 改自己的模板就能修,一改全组受益 |
| 2 | 指向已经不存在的页面 | 零风险,直接删 |
| 3 | 指向会跳转的地址 | 把声明改成跳转终点即可,也在自己手里 |
| 4 | 默认版本标法不一致 | 要先在内部定口径,再一次性同步 |
| 5 | 对面不列你 | 要跨团队,周期最长,放最后 |
这个顺序的逻辑是先做完全在自己手里的,再做需要别人配合的。前三项通常能解决掉大半问题,而且当天就能上线。
有一点要提醒:别把第五项当成拖延前四项的理由。实践中很常见的一种状况是,团队盯着推不动的那一项反复开会,而自己模板里那个缺自指的问题挂了大半年没人改。前者是别人的进度,后者是自己的进度,混在一张表里汇报,最后两边都停在原地。
把两类分开排期、分开汇报,是这件事能推下去的关键。自己那部分改完就能拿到确定的收益,别人那部分再慢慢磨。
把核对做成例行的三个触发点
定期巡检对这件事效果一般,因为问题不是匀速产生的,它集中在几个特定时刻。更有效的是把核对挂在这三个触发点上:
第一,新增或下线一个市场时。这是最大的一次变更,必须全组同步。
第二,任何一个国家站做地址结构调整时。这一条需要提前跟各市场团队约定:改地址前先通知。
第三,每次做站点迁移或换建站系统时。这类动作最容易把整块声明弄丢。
还有一个偷懒但有效的办法
如果集群规模大到手工维护不动,可以把这套声明从页面上挪到清单文件里——规范允许在站点地图里表达同样的关系,而站点地图是程序生成的,天然带一个每次导出都重算的触发点。
它的代价是可读性变差、排查更麻烦,而且不解决对面不配合的问题。但它至少把你自己那一半从手工维护变成了自动生成,这已经能砍掉相当一部分错误。
把核对写成一段脚本,逻辑就这几步
不想每次手工做的话,这段逻辑不难写,核心不到五十行。
输入是一批本站地址。第一步抓每个页面,解析出它的声明清单,同时记下它的规范网址。第二步检查规范网址是不是指向自己,不是就直接标红,后面都不用查了。第三步检查清单里有没有自己。第四步把清单里所有目标地址去重,做归一化,然后逐个抓,记状态码和最终落地地址。第五步解析每个目标页的清单,跟源页做集合比对,同时比每个共有地址的标法。
三个容易写错的地方要提一句。一是归一化必须做,否则尾斜杠和大小写会制造大量假问题。二是非正常状态必须换身份重抓一次,否则失败率会虚高。三是要按最终落地地址去比,不是按声明地址,跳转会让后者失去意义。
输出建议分成两张表:自己能修的和要找别人的。这两张表的处置节奏完全不同,混在一起会让前一张也拖着。
还有一件小事值得提前想:这段脚本抓的是别人的站,频率要收着点。每个域之间留一两秒间隔,别开太高的并发。跨域目标里有相当一批带着地区级的防护策略,一次密集请求就可能把自己的出口地址拉进黑名单,之后你连正常核对都做不了。
另外,脚本跑出来的结果要留一份带时间戳的存档。这类问题往往要来回几轮才能推动,半年后再看时,能拿出当初那份记录说清楚哪些是新出的、哪些是一直没改的,比重新解释一遍有说服力得多。
常见问题解答
只有我这边写了,对方没写,能生效吗?
不能。规范明确要求这套声明必须双向成立,且每个成员都要包含自己。搜索引擎的处理方式是把单向的那条忽略掉——它没法确认这门关系是不是你单方面声称的。实测240个目标页里,有12个漏了自指,还有6个一条声明都没有,这两类都会导致整组关系不成立,哪怕别的成员都写对了。
怎么快速判断我的站有没有这个问题?
最快的一步是查自指:打开任意一个语言版本的页面,看它的清单里有没有它自己。没有就是硬伤,而且这一条改自己的模板就能修。接下来抽三到四个目标地址实抓,看能不能打开、有没有跳转、打开之后列不列你。整套下来半小时以内,实测里19.2%的站会在这一步就暴露问题。
目标地址打不开,一定是对方的问题吗?
不一定。实测18条打不开的目标里,7条换成普通浏览器身份重抓就正常了,占38.9%。原因通常是对方的防护策略不接待自动化请求,或者做了地区级访问限制。所以看到失败先换个身份再试一次,不然失败率会被虚报——本文这批数据不做这一步会写成7.0%,做完是4.3%。
同一个地址被两边标成不同语言,要紧吗?
分情况。如果是普通的语言地区标法不同,搜索引擎通常会忽略有分歧的那一条,其余照常生效,影响有限。如果分歧出在谁是默认版本上就比较麻烦——整组说不清兜底页是哪个,搜索引擎只能自己挑。实测8894次比对里1758次标法不同,占19.8%,而头部几组全部围绕默认版本这一件事。
声明的地址会跳转,需要改吗?
需要。搜索引擎抓到的是跳转终点,而终点页面上列的是它自己那一套,很可能不包含你写的那个原地址,于是两侧对不上。实测240个能打开的目标里32个跳到了别处,占13.3%,而且多数站是抽到的几条全中,说明是站点级规则。改法很简单:把声明直接写成跳转终点的地址。
跨域声明是不是应该避免?
不用避免,规范本来就允许。实测21个站写了跨域声明,一共277条。真正的风险不在跨域本身,在于另一头归谁管——同一个团队的不同国别域基本没问题,跨部门和跨公司的才难维护。一个可以参考的负结果是:39个能对照的跨域目标,平台指纹全部与源站相同,说明技术上是通的,障碍主要在组织上。
集群太大维护不动,有什么办法?
可以把这套关系从页面挪到站点地图里表达,规范允许两种写法。好处是站点地图由程序生成,每次导出都会重算,天然带一个更新触发点,不像模板里那几行会一直不动。代价是可读性和排查便利性都变差,而且不解决对面不配合的问题。适合语言版本超过十几个、又确实维护不动的站。
对面团队推不动怎么办?
短期内推不动的话,先把自己这边指向对方的那一条删掉。单向声明本来就不生效,留着只会让每次核对都报同样的错,白白消耗注意力。等对方能配合了再一起加回来。要注意删掉不等于放弃那个市场,那个页面照常被收录和排名,只是少了一层语言定向。沟通时带上具体地址清单、对方要加的代码原文、以及这件事对他们自己市场的收益,比讲规范有效得多。
权威参考资料
本文标题:《hreflang互指对不上,多半是另一边先改的》
本文链接:https://zhangwenbao.com/hreflang-cluster-reciprocity-third-party-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0