运费写着发到加拿大,退货政策上只有美国这一个国家
本文目录
- 一份报价里,能写地域的字段其实不止一个
- 70个产品页是怎么筛出来的?
- 那11份运费声明,管的是几个国家?
- schema.org给了三个专门划地域边界的字段,为什么一个都没人用?
- 声明服务200个地区的站,在产品页上写了哪个国家?
- 运费写着发到加拿大,退货政策上只有美国这一个国家
- 一个北美牌子的退货政策,为什么写着新加坡?
- 地区网址到底管不管用?我拿hreflang挨个试了一遍
- 说无限期退货又写着30天,这份声明该信哪一句?
- areaServed写在公司那一层,和写在报价那一层,不是一回事
- 边界之外的买家,AI购物代理替他们看到了什么?
- 自己站上这几层地域声明,怎么排查?
- 常见问题解答
- 产品结构化数据里的运费和退货字段,不写会怎样?
- applicableCountry和returnPolicyCountry有什么区别?
- 我的站只卖本国,是不是就不用写这些字段?
- schema.org里的eligibleRegion能不能用来表达报价的地域范围?
- 为什么我用工具抓自己的产品页,看到的货币和实际不一样?
- hreflang里声明了很多地区,产品页上只写一个国家,算不算错?
- 退货政策写成对同页另一个块的引用,会有问题吗?
- 权威参考资料
摘要:70个能从产品页静态HTML里读到商品结构化数据的海外品牌站,价格和货币的填写率是100%,而写明这份报价管哪些国家的只有11个。更值得看的是这11个里面的分布:运费声明的国家数中位数是1,退货政策的适用国全是单一国家,10个写US、1个写SG,没有一个写了两个以上。与此同时,这批站里有人在hreflang里声明自己服务57个地区,有人声明200个。schema.org准备了eligibleRegion、ineligibleRegion、availableAtOrFrom三个专门用来划地域边界的字段,70个产品页的使用次数是0。
一个商品页上的结构化数据,本质上是一份写给机器看的报价单。价格多少、什么货币、有没有货——这三样几乎人人都填。
但报价单还有一栏,很多人从没想过要填:这份报价对谁有效。
这一栏不是可有可无的修辞。一件商品标价49美元,含不含运费、发不发到你所在的国家、买回去能不能退,在不同的国家是完全不同的答案。人看页面的时候,这些信息散落在页脚、配送页、结账第三步;机器读结构化数据的时候,只认那几个专门的字段。字段空着,机器拿到的不是“不适用”,而是“不知道”。
这次要量的就是这一栏——一份报价的地域作用域到底写到哪儿,边界之外那些买家发生了什么。方法是从131个海外品牌站的sitemap里各挑一个商品页抓下来,把结构化数据整段拍平,逐个字段核。
一份报价里,能写地域的字段其实不止一个
先把可用的工具摆出来。围绕商品报价这一层,schema.org提供的地域相关字段至少有六个,各管一段——运费声明这一类和退货政策这一类各自还带着一组子字段:
| 字段 | 挂在哪一层 | 它划的是什么边界 |
|---|---|---|
| shippingDetails的shippingDestination | Offer下的运费声明 | 这个运费方案发往哪些国家 |
| hasMerchantReturnPolicy的applicableCountry | Offer下的退货政策 | 这份退货政策适用于哪些国家的买家 |
| returnPolicyCountry | 同上 | 退货要寄到哪个国家(和上一条不是一回事) |
| eligibleRegion | Offer | 这份报价在哪些地区有效 |
| ineligibleRegion | Offer | 这份报价在哪些地区无效 |
| areaServed | Organization等 | 这个组织服务哪些地区 |
这六个字段不是同义词的堆砌,它们各自的主语不一样。前三个的主语是“这一份报价”,中间两个的主语也是报价但表达的是可用与不可用两个方向,最后一个的主语是“这家公司”。填错了层,说的就不是同一件事。
层次这件事在结构化数据里反复咬人。小语种页面的正文越本地化越好、结构化数据里却要反着写回国际格式,讲的也是同一类分寸:给人看的那一层和给机器看的那一层,规矩是两套。
70个产品页是怎么筛出来的?
分母这件事必须先摊开,因为这类审计最容易犯的错就是把“我没抓到”算进“它没有”。
131个站,先从robots.txt里找sitemap入口,再从sitemap索引里挑出商品那一份,取一条商品URL抓回来。走到最后能读到Product或ProductGroup声明的,是70个。
| 结果 | 站数 |
|---|---|
| 拿到了带商品声明的产品页(本文的分母) | 70 |
| 连一条商品URL都没找到(sitemap取不回或形态不匹配) | 38 |
| 页面取回来了,但没有商品类型的声明 | 12 |
| 页面取回来了,一段结构化数据都没有 | 9 |
| 找到URL但页面取不回(403等) | 2 |
那38个不是“没有结构化数据”,只是我这套取样方式够不着——有的站robots.txt对这个客户端关门,有的商品URL形态特殊。它们不进任何比例。中间那21个(12加9)倒是可以单独记一笔:页面确实拿回来了,商品声明却是空的。这类“页面在、内容读不到”的情形有好几种成因,页面体积那次46个电商站的实测量过其中最物理的一种。
还要说明一件事:配送与退货承诺说给人听还是说给机器听这个问题,之前用136个站的首页量过一轮,答案是63对11。这次不重复那笔账。这次问的是下一个问题——那些确实写给了机器的,写清楚管谁了吗。
那11份运费声明,管的是几个国家?
先看这70个产品页各层字段的填写情况:
| 字段 | 有的站数 | 占70 |
|---|---|---|
| priceCurrency(这钱是什么币) | 70 | 100% |
| price(多少钱) | 69 | 98.6% |
| availability(有没有货) | 68 | 97.1% |
| seller(谁在卖) | 24 | 34.3% |
| hasMerchantReturnPolicy(退货政策) | 13 | 18.6% |
| shippingDetails(运费方案) | 11 | 15.7% |
| applicableCountry(退货管哪国) | 11 | 15.7% |
| shippingDestination(发往哪国) | 10 | 14.3% |
| returnPolicyCountry(退到哪国) | 2 | 2.9% |
| areaServed(服务哪些地区) | 2 | 2.9% |
真正要看的是下面这张。写了shippingDestination的10个站,各自写了几个国家:
| 站点 | 写了几个国家 | 写的是 |
|---|---|---|
| outdoorvoices.com | 2 | US、CA |
| bollandbranch.com | 1 | US |
| brooklynbedding.com | 1 | US |
| graza.co | 1 | US |
| hellotushy.com | 1 | US |
| jackery.com | 1 | US |
| ruggable.com | 1 | US |
| taylorstitch.com | 1 | US |
| ikea.com | 1 | EE(爱沙尼亚站) |
| flyingtiger.com | 0 | 引用了另一个块,块里没写国家 |
中位数是1。最大值是2,还是唯一的那一个。
退货政策那一栏更整齐:11个写了applicableCountry的站,没有一个填了两个以上的国家——10个写US,1个写SG。
这个“1”值得停一下。它不必然是错的:一个只做美国本土生意的品牌,运费方案和退货政策都只覆盖美国,写1个国家是诚实的。所以下面几节要做的事,是把“只写1个”和“实际只卖1个国家”这两件事分开量。
schema.org给了三个专门划地域边界的字段,为什么一个都没人用?
eligibleRegion的用途是直说“这份报价在这些地区有效”,ineligibleRegion是反过来“这些地区不适用”,availableAtOrFrom则是“从哪里发出”。三个字段的语义比运费和退货更靠近“作用域”这件事本身。
70个产品页里,这三个字段的出现次数分别是0、0、0。
零使用的原因大概不难猜:主流搜索引擎的商品结构化数据文档里,推荐字段清单上没有它们。文档推荐什么,工具生成什么,模板里就有什么。schema.org是一套完整的词汇表,但真正被填的永远是被某个下游消费者点过名的那几个格子。
这个“没人点名就没人填”的规律,在别的机器可读界面上也一样。接口和feed这类地址连head标签都没有,能用的表达手段本来就少,最后能被用起来的就更少。
这带来一个连锁后果:整个行业表达“地域适用范围”的能力,就这样被压缩到了运费和退货这两个字段上。而这两个字段的主语是运费方案和退货政策,不是报价本身。想说“这个价格只对欧盟买家有效”,目前没有一个被广泛消费的字段能表达它。
声明服务200个地区的站,在产品页上写了哪个国家?
把地域这件事的另一份声明接过来对一下就清楚了。hreflang是站点自己列出的“我为哪些语言和地区准备了页面”,它是站点对市场范围最公开的一次表态。
70个产品页里带hreflang的有33个,声明的地区数中位数是5,最多的一个是200。
| 站点 | hreflang声明的地区数 | 产品页写明的运费国 | 写明的退货国 |
|---|---|---|---|
| liquiddeath.com | 200 | 0 | 0 |
| aloyoga.com | 192 | 0 | 0 |
| glossier.com | 186 | 0 | 0 |
| nomadgoods.com | 57 | 0 | 1 |
| rothys.com | 34 | 0 | 0 |
| beistravel.com | 30 | 0 | 0 |
| allbirds.com | 26 | 0 | 0 |
| govee.com | 22 | 0 | 0 |
| rapha.cc | 19 | 0 | 0 |
| mejuri.com | 15 | 0 | 0 |
| ruggable.com | 11 | 1 | 1 |
把这张表读透一点:公开声明自己服务2个以上地区的站有18个,其中在产品页上写明了报价管哪个国家的,只有ruggable和nomadgoods两个。剩下16个站的产品页上,那一栏是空的。
而写了的那两个也不能算写全。ruggable在hreflang里列了11个地区,产品页上的运费和退货各写了1个国家,作用域差了一个数量级。这不是笔误,是这套字段的常见用法——同一个模板输出所有地区的页面,那个国家码来自当前这一版的市场设置,其他10个市场各有各的页面、各有各的那一行。问题是抓到任何一版的机器,只会看到一个国家。
这份声明还有一个前提性的毛病:两边得互相指认才算数。互指对不上的时候,多半是另一边先改的,而单向标注在多数消费方眼里等同于没写。
顺便说一句,hreflang这份声明本身也常常不准。236条地区声明背后只有6个真页面那次实测量过这个落差,所以上表左边那一列该读成“站点自称的市场范围”,不是“实际能下单的国家”。
运费写着发到加拿大,退货政策上只有美国这一个国家
七个站同时写了运费国和退货国,可以两两比对。结果是6个一致,1个不一致。
那个不一致的是outdoorvoices:运费方案写着发往US和CA,退货政策的applicableCountry只写了US。
这一个字的差别,落到具体的人身上是这样的:一个加拿大买家,机器告诉他能收到货;等他想退,机器手上那份政策不覆盖他。它不等于“不能退”——真实的退货政策多半在网站的某个页面上写着,人工客服也一定有答案。它等于“机器不知道能不能退”。
这两件事的差别,在人来问的时候不大,在机器替人问的时候很大。人会接着往下翻,机器不会,它只会把这一栏留白,或者在比较几家店的时候,把留白的那家排在写清楚的那家后面。
这类“承诺的适用范围比承诺本身更难说清”的形态,在配送时效上也一样。你写的是2个工作日,他记的是周四说的是同一件事的时间维度:一个没算完的承诺,双方各自补完了后半句,补出来的还不一样。
一个北美牌子的退货政策,为什么写着新加坡?
前面那11个退货国里,唯一不写US的是nomadgoods,写的是SG。这个站是加州的配件品牌,它的产品页URL没有任何地区前缀,hreflang里en-US那一条自指向的正是我抓到的这个地址。
看到这一条的第一反应是“模板默认值填错了”。但这个解释经不起一次简单的复核。
我把它hreflang里的四条地区URL——美国、英国、新加坡、加拿大——挨个抓了一遍:
| hreflang | URL | 抓回来的货币 | 抓回来的退货国 |
|---|---|---|---|
| en-US | /products/… | SGD | SG |
| en-GB | /uk/products/… | SGD | SG |
| en-SG | /sg/products/… | SGD | SG |
| en-CA | /ca/products/… | SGD | SG |
四个不同的地址,四份一模一样的答案。这套地区版本是怎么被选定的,平台自己的本地化文档里写得很清楚:地址只是其中一个输入,访客位置是另一个。所以填错的不是模板,是我的出口线路把这套页面整体切成了新加坡版本——那几段地区路径根本没被当回事,决定这一页内容的是请求方的位置。
这条尺子偏差影响的不止一个站。整批数据里priceCurrency出现SGD的有9处,其中相当一部分并不是这些品牌真的在用新加坡元定价,而是我这次的观测位置留下的指纹。另一个mackweldon就更直白:响应里带回了一个写着SG的本地化Cookie,页面语言标成en-SG,货币SGD,而它结构化数据里的areaServed写的是US。
把这件事说穿了,它其实是本文主题的一个更狠的版本:你以为一份报价的作用域是由地址决定的,而在这些站上,它是由访客的位置决定的,地址和hreflang两份声明都不知情。
地区网址到底管不管用?我拿hreflang挨个试了一遍
上一节冒出来的问题必须回答清楚:这种“地址说了不算”的站到底是少数还是多数?只看一个样本就下结论,是在替自己找证据。
所以对全部28个有多条地区URL的站,各抓最多4条不同地区的商品页,比对拿回来的货币。判据是:
- 各URL回不同货币,说明报价的作用域由地址决定,地区站是真的
- 各URL回同一种货币,说明作用域由请求方位置决定,地址只是摆设
第一版结果是17比9。但这个数字有个漏洞,而且漏得很难看:欧元区十几个国家共用一种货币——如果我抽到的四条恰好是德国、意大利、西班牙、荷兰,那么四条都回EUR是完全正常的,它证明不了任何事。我把这类“抽到的地区本来就同币”的样本单独摘出来,重新分类:
| 判定 | 站数 | 含义 |
|---|---|---|
| 地址决定 | 15 | 不同地区URL回不同货币,地区站是真的 |
| 位置决定 | 3 | 跨了不同币区的URL,货币仍然一样 |
| 币区不可分 | 8 | 抽到的地区本来就共用一种货币,判不了 |
| 样本不足 | 2 | 能读到货币的URL不够2条 |
修正之后,“位置决定”那一栏从9掉到3。掉下去的6个全是欧元区内部的抽样。方向值得留意——错的那一版恰好指向“更有故事”的那一边,这种时候第一个该被怀疑的是尺子,不是结论。
那3个站是beistravel(US、GB、CA、BE四个不同币区全部回USD)、harrys(US和GB都回USD)、nomadgoods(US、AU、CA、GB全部回SGD)。
一套模板输出几十版页面这件事本身也有代价。一个模板生成十种语言,字符层看不出重复、信息层十份一模一样,地域字段只写当前那一版的国家码,正是这个形态在数据层的表现。
还有一个更细的观察:在“地址决定”那15个站里,有4个的默认版本(没有地区码的那条根URL)仍然是按位置切的,只有带地区码的地址才严格按地址走。也就是说同一个站上,两种规则同时在跑,取决于你落在哪个地址上。这层复杂度会一路传导到收录——hreflang里那些语言版本被当成规范页的别名说的就是它的下一站。
说无限期退货又写着30天,这份声明该信哪一句?
把13份退货政策原样铺开,还能看到几处内部打架的写法。
| 站点 | 退货窗口类型 | merchantReturnDays | 问题 |
|---|---|---|---|
| dreametech.com | 无限期退货窗口 | 30 | 两个字段互斥,一个说没有期限,一个说30天 |
| buckmason.com | 有限期 | 365 | 一致 |
| taylorstitch.com | 有限期 | 21 | 一致 |
| 其余8个 | 有限期 | 30 | 一致 |
| fromourplace.com | 字段在,值是空数组 | — | 写了等于没写 |
另外6个站把运费和退货政策写成了对同页另一个块的引用(形如指向某个内部锚点),块本身在同一页的别处。这种写法是合法的,只是任何一个不做引用解析的读取方,看到的就是一个空壳。我第一版的统计脚本就是这么被绊了一下,把引用当成了内容。
还有一个小得几乎不值一提、但很能说明这些字段是怎么被生成的细节:availability这个字段在样本里出现了4次带前导空格的取值,写成空格加InStock。它多半来自某段模板拼接时没有裁掉的换行。这类字符级的瑕疵在自填字段里非常常见,商品属性被静默丢弃那篇量过它们最终会被消费方怎么处理——通常是整条丢掉,不给任何提示。
areaServed写在公司那一层,和写在报价那一层,不是一回事
70个产品页里写了areaServed的只有2个,正好是两种典型用法。
rothys写的是35个国家码的一整串,从阿根廷到美国,覆盖了它hreflang里那34个地区还多一个。这份清单是准的,问题在于它挂在组织那一层——它说的是“这家公司服务这些地区”,不是“这件商品的这个价格在这些地区有效”。对一个只想知道“我这儿能不能买、多少钱”的读取方来说,这份清单帮不上忙。
mackweldon写的是单个US。而如前所述,它同一份响应里带回的本地化Cookie写着SG,页面语言标着en-SG。这一页上“这家公司服务美国”和“这一页是给新加坡访客的”并排放着,两句话各自都没错,合起来读却讲不通。
这就是层次问题的实际后果:组织的服务范围、页面的目标地区、报价的适用国家,是三个不同颗粒度的边界,它们可以互不包含。把其中任意一个当成另外两个用,读的人不会报错,只会得出一个错的结论。
同一份东西在不同层上各写一遍、各写各的,是结构化数据里的常见病。首页的title、og:title和H1说的常常不是同一件事,量的是同一种毛病在描述层的样子。而在贸易那一侧,责任边界写在哪一刻交接是有成文规则的——FOB还是CIF,风险在哪一刻从你手里交出去,那套术语存在的全部理由就是不让边界含糊。
边界之外的买家,AI购物代理替他们看到了什么?
这一栏空着,在过去只影响商品富媒体展示里的运费和退货那两行小字——商品列表那份文档写明了没提供时会退回到商家后台的配置。现在影响的东西多了一层。
当买家把“帮我找一双能发到加拿大、支持免费退货的鞋”这句话丢给一个AI助手,助手要做的事是从一堆商品数据里筛出符合条件的。它筛的依据只能是它读得到的字段。运费国和退货国那一栏空着的商品,在这个筛选里的处境不是“被排除”,而是更尴尬的“无法判断”——保守的实现会跳过它,激进的实现会猜一个,而猜的依据往往是站点的其他信号,比如货币、语言、公司地址。
更麻烦的是,这些代理拿到的常常不是实时页面,而是某个时点抓下来的快照。前面那个“内容跟着请求方位置走”的现象在这里会被放大:抓取端在哪儿,快照里就是哪个市场的价格和政策,而快照上不会写着“这是从新加坡节点看到的版本”。
而且这类筛选很不稳。AI推荐名单只要被追问一句就少掉六成,追问里若带着国家或运费条件,字段空着的商品最先掉出去。
这一层的信息会怎么被重新组织、又会被派成什么角色,同一条来源在不同引擎里被派成不同角色那篇拆过机制;具体到商品页该补哪些结构化信息才让机器读得懂,面向AI推荐的产品页优化列过一份清单。地域字段是那份清单里最容易被跳过、也最容易被误读的一组。
自己站上这几层地域声明,怎么排查?
不用等做全站改造,先拿一个商品页做四件事。
- 把这一页的结构化数据整段拍平,搜六个字段名:shippingDestination、applicableCountry、returnPolicyCountry、eligibleRegion、ineligibleRegion、areaServed。一个都搜不到,说明这一页从没表达过地域范围。
- 数一数自己hreflang里有几个地区,再和上一步搜到的国家数放在一起看。前者远大于后者,就是本文量到的那个落差,你的每一版页面都只说了自己那一个市场。
- 换一条线路再抓一次同一个URL。用一台在别的国家的服务器,或者任何一个能改变出口位置的方式,比对两次拿到的货币和国家码。如果变了,说明你的地址不是决定内容的那个变量——这件事你自己不测,抓你的机器也不会告诉你。
- 检查引用式写法。如果运费和退货政策是用锚点引用同页另一个块,确认那个块真的存在且填了内容,并且做好被不解析引用的读取方看成空的准备。
做完这四步,多半会发现真正要改的不是模板里少写了一个字段,而是没人想清楚“这份报价管谁”这句话应该由哪一层来回答。是每个市场的页面各说各的,还是在一份数据里把所有市场列全,这是个架构选择,不是填空题。保哥自己给客户做的那次盘点里,最后卡住的也是这个问题——运营部门认为退货政策是全球统一的,法务给出的版本按地区分了三档,而模板里只有一个国家码的位置。
如果你还要把商品数据喂给比价平台或者广告渠道,那就是又一份要维护的清单——站上加一门语言是加一套模板,喂给平台的那份数据要多一整份文件,地域字段在那份文件里通常是必填项,比页面上还严。生成hreflang本身也有坑,生成器给的sitemap代码粘上去往往是单向标注。
顺带提一句排查顺序:这几层声明里最先该对齐的是hreflang和实际能下单的市场,其次才是产品页字段。上游那份清单本身如果就是虚的,下游填得再全也只是把错误抄了一遍。这条链路怎么按模板抽样查完,电商SEO审计按模板抽样那篇给过一个能在半天内跑完的做法。
常见问题解答
产品结构化数据里的运费和退货字段,不写会怎样?
不会报错,也不会被判罚,但商品富媒体展示里的运费和退货那两行就没有数据来源,搜索引擎要么留白、要么退回到商家后台的配置。更实际的影响在AI购物助手这一侧:当用户的问题里带着“能不能发到某国”“支不支持免费退货”这类条件时,字段空着的商品在筛选里是“无法判断”,不是“符合”。
applicableCountry和returnPolicyCountry有什么区别?
applicableCountry说的是这份退货政策适用于哪些国家的买家,returnPolicyCountry说的是退货要寄回哪个国家。两者可以不一样——比如面向欧洲多国销售、但统一退回德国仓。实测70个产品页里写了前者的有11个,写了后者的只有2个,而这2个都是两个字段一起写、且填的是同一个值,说明这个区别在实践中基本没被用起来。
我的站只卖本国,是不是就不用写这些字段?
仍然建议写。只卖一个国家的时候,写上那一个国家码的成本几乎为零,收益是把“只管这一国”这件事明确说出来,而不是留给对方去猜。实测里10个站的退货政策只写US,其中大部分确实是单一市场品牌,这种写法是准确的。真正的问题出在同时服务多个市场却只写一个国家的那些站上。
schema.org里的eligibleRegion能不能用来表达报价的地域范围?
语义上完全可以,它就是为这件事准备的。但实测70个产品页的使用次数是0,原因是主流搜索引擎的商品结构化数据文档没有把它列进推荐字段,工具和模板也就不生成它。如果你的目标是被搜索引擎的商品展示消费,先把文档点过名的那几个字段填好;如果目标是让更多类型的读取方理解你的报价范围,补上它没有坏处。
为什么我用工具抓自己的产品页,看到的货币和实际不一样?
很可能是抓取端的位置触发了站点的地区切换。实测中有3个站的多个地区URL全部返回同一种货币,说明决定内容的不是地址而是请求方位置。排查方法是换一条不同国家的线路抓同一个URL,比对结果;如果两次不同,那么任何一个不在你目标市场的抓取端,看到的都是另一个版本的报价。
hreflang里声明了很多地区,产品页上只写一个国家,算不算错?
不算写错,但确实是信息缺失。多市场站通常是一套模板输出所有地区的页面,每一版页面上的国家码来自当前那个市场的配置——单看任何一版都是对的,问题是任何一个读取方也只会看到一版。想让完整的市场范围被读到,要么在同一份数据里把多个国家列全,要么确保每个市场的页面都能被独立抓到。
退货政策写成对同页另一个块的引用,会有问题吗?
规范上没问题,被引用的块在同一页里就能解析。风险在于不是所有读取方都会做引用解析——不解析的那些拿到的是一个只有标识符的空壳。实测里有6个站用了这种写法。如果你不确定下游会怎么处理,把内容内联写一份是更保险的选择。
权威参考资料
本文标题:《运费写着发到加拿大,退货政策上只有美国这一个国家》
本文链接:https://zhangwenbao.com/product-offer-geographic-scope-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0