一张礼品卡的结构化数据119KB,同一段配送政策抄了60遍

一张礼品卡的结构化数据119KB,同一段配送政策抄了60遍
张文保 23 分钟阅读 3,174 阅读
本文目录
  1. 一个商品页往外发多少字节的结构化数据?
  2. 按体积分档,两头都不小
  3. 最大的那一页有232KB,里面装的是什么?
  4. 先把边界划清楚
  5. 44种类型摊开,哪几种把节点数撑起来了?
  6. 一个有用的旁证:Organization和Product几乎一样多
  7. 一件商品的配送政策,为什么被抄了60遍?
  8. 这个坑几乎全是模板循环造成的
  9. 导航菜单为什么会出现在商品页的结构化数据里?
  10. 这些Product节点是从哪儿长出来的?
  11. 展开到251个,还是不是那个推荐做法
  12. 同一个站,热门款和长尾款的差距有多大?
  13. 有多少商品页干脆什么都不写?
  14. 另外7个页面的JSON解析直接失败
  15. 我这把尺子量到的,是等了4秒之后的那一版
  16. 自己站上这份清单怎么数?
  17. 第一步:先看总量落在哪一档
  18. 第二步:按类型排序,找出现次数远超页面数的那几种
  19. 第三步:把重复的对象改成引用
  20. 第四步:删掉那些没有对应展示形式的类型
  21. 一个反例:什么时候不该删
  22. 什么时候这套检查不该做
  23. 常见问题解答
  24. 商品页的结构化数据太大,Google会不会因此不收录?
  25. 变体全部展开成Product节点,到底该不该做?
  26. 用@id引用代替复制,会不会影响搜索引擎理解?
  27. SiteNavigationElement现在还有用吗?
  28. 一页有多个ld+json标签,是不是也算问题?
  29. 只统计JSON-LD会不会漏掉很多?
  30. 怎么知道搜索引擎实际读到的是哪一版?
  31. 权威参考资料

摘要:53个英文独立站的392个商品页,逐页把结构化数据取下来数了一遍。一页的JSON-LD中位数是4217字节,可四分之一的页面超过13KB,最大的一页有237214字节。最大那几页装的东西很有意思:一张电子礼品卡把同一段配送政策和退货政策照着60个面额抄了60遍,一件毛衣的每个尺码都带着一份门店营业时间,一个旅行箱品牌把82条导航菜单写进了每一个商品页。全样本13383个节点分属44种类型,而在一个页面里,真正描述这件商品本身的那个节点,中位数只占整页节点的10%。

一个商品页往外发多少字节的结构化数据?

这个数我以前没量过,凭感觉估的是两三KB。毕竟一件商品能写的东西就那么多——名字、价格、库存、图片、品牌,撑死了几十行。

实测下来,中位数确实是4217字节,跟感觉差不多。但中位数在这件事上基本没有参考价值。

样本是53个英文独立站,每个站挑8件商品,用真实浏览器打开商品页,等页面渲染完再把所有script[type="application/ld+json"]的内容取下来,逐个节点数。最后有392个页面拿到了可解析的结果。

指标中位P75P90最大
JSON-LD字节数42171344726518237214
节点数163883636
Product节点数1615251
script标签数2346

从中位到最大,字节数差了56倍。这不是几个离群点的问题,是整批数据本来就分成两个世界:一半的站老老实实写商品,另一半在往这块地方倒东西。

按体积分档,两头都不小

这一页的JSON-LD页数占比
一个字节都没有123.1%
不到1KB256.4%
1到4KB15439.3%
4到10KB8421.4%
10到30KB8621.9%
超过30KB317.9%

接近三成的商品页,光结构化数据这一块就超过10KB。作为参照,一份写得完整的商品标记——名字、描述、图片、品牌、一个报价、一条评分——大约在800到1500字节。

也就是说,超过10KB的那批页面,多写出来的部分是必需内容的七倍以上。这些字节要经过压缩、传输、解析,还要占掉抓取时读到的那部分预算。页面体积实测46个电商站那次量的是整页HTML的字节,这次量的是其中专门写给机器看的那一块。

这一块有个特点:它不出现在任何一张设计稿上,改版评审也没人打开看。DOM元素数量那次实测好歹还有个开发者工具的元素面板能翻,结构化数据连翻的人都没有——它躺在源码里,谁也不打扰谁,直到有一天它比商品描述还长。

最大的那一页有232KB,里面装的是什么?

把最大的几页拆开看,比看分布有意思得多。

页面字节节点节点构成
rothys.com的一双平底鞋237214636250个Product+250个Offer+131个单价说明
rothys.com的另一款155148412204个Product+204个Offer
hellotushy.com的电子礼品卡11902948660个Offer,每个各带7个附属节点
stanley1913.com的保温杯11873519042个变体+43个Organization+42份退货政策
taylorstitch.com的针织衫10046133230个变体,每个带10个附属节点

第一页那双鞋,636个节点里有250个是它的尺码。这批节点每个只写了一个网址,名字、图片、描述、报价一律空着——它们存在的唯一意义是告诉机器这个尺码有个地址。

顺带一提,这一页的可见正文只有1479个字符。232KB的机器可读数据,配1479个字符的人类可读文字,比例是160比1。这个站的商品信息几乎全在图片和交互组件里,纯文本那一层很薄。一个只读文字的抓取方来到这一页,能拿走的东西还没有它读进去的零头多。

先把边界划清楚

这一篇量的只有JSON-LD,不含微数据和RDFa。这个取舍会让某些站的数字偏低——比如hellotushy,我复验的时候在它一个页面上数出211个带itemtype的微数据元素,图集、图片对象、问答全在那一层,而JSON-LD里一个都没有。一次扒清页面五种格式的字段缺漏那篇讲过为什么审计工具要同时认五种格式,原因就在这儿。

另外三个站的数据从统计里剔掉了,理由各不相同:dreametech的8个页面全部返回Access Denied,那是反爬拦住了我,不是它没写;oclean的8个商品地址全部跳到了越南站首页,拿回来的根本不是商品页;ugreen的商品地址在采集时全部404。这三个站留在样本里,得出的每一个百分比都是假的。

44种类型摊开,哪几种把节点数撑起来了?

全样本13383个节点,分属44种schema.org类型。前几名是这样:

类型节点总数出现在多少页
Offer3007362页(92%)
Product2550366页(93%)
Organization1020295页(75%)
QuantitativeValue76072页(18%)
SiteNavigationElement6568页(2%)
Brand420326页(83%)
Question/Answer各41437页(9%)
MerchantReturnPolicy38955页(14%)

这张表最值得看的是第三列。Offer出现在92%的页面上,属于正常配置;而SiteNavigationElement有656个节点,却只出现在8个页面里——平均每页82个。QuantitativeValue也一样,760个节点挤在72页。

换句话说,节点数的膨胀不是普遍现象,是少数站的少数几种类型在集中发力。

一个有用的旁证:Organization和Product几乎一样多

1020个Organization节点,2550个Product节点。一个商品页需要几个Organization?一个就够,写清楚卖家是谁。可stanley1913那个保温杯页面上有43个,正好等于它的变体数——每个变体的报价里都完整重写了一遍卖家信息。

这不是它一家的做法。凡是把变体展开的站,只要报价里写了seller,Organization就会跟着翻倍。商品品牌字段那次实测发现同一个品牌能被写成好几种拼法,这次看到的是同一个卖家被原样复制几十份,两件事的成因是同一个:这些结构是模板循环里拼出来的,没有人从整页的角度看过最终结果。

一件商品的配送政策,为什么被抄了60遍?

hellotushy那张电子礼品卡是本批最干净的样本,因为它只有1个Product节点,膨胀跟变体完全无关。

它的486个节点是这么构成的:60个Offer,对应礼品卡的60个面额。每个Offer下面挂着一份OfferShippingDetails、一份MonetaryAmount、一份DefinedRegion、一份ShippingDeliveryTime、一份MerchantReturnPolicy,外加两份QuantitativeValue。60乘以7,420个节点。

一张电子礼品卡是不需要配送的。但模板不管这个,模板只知道每个报价都要带上店铺的配送与退货配置,于是60个面额各拿到了一份一模一样的物流承诺,连退货政策都齐全——一张发到对方邮箱里的电子卡,配了60份退货说明。

taylorstitch那件针织衫更进一步:30个尺码,每个尺码除了上面这套,还额外带一份OpeningHoursSpecification。一件毛衣的每个尺码,都在告诉搜索引擎这家店周一到周日几点开门。不是这家店开三十次门,是这个信息被抄了三十遍。

这类节点本身没写错。配送和退货承诺那次实测说过,把承诺写成机器可读是件好事,136个首页里只有11个做到了。问题在于写的位置——它应该挂在店铺层,不该跟着每一个报价复制一遍。

这个坑几乎全是模板循环造成的

我把这类重复的成因归了三类,每一类的修法完全不同:

成因典型表现怎么改
店铺级配置写进了报价循环每个Offer带一份配送与退货政策提到Organization或ProductGroup那一层,用引用而不是复制
卖家信息写进了报价循环Organization数量等于变体数量同上,写一次,其余用@id引用
站点级结构写进了每个页面导航菜单出现在商品页直接删,这一类不该出现在商品页

第一类和第二类有个共同的正解:JSON-LD支持用引用代替复制,把重复的对象写一次,其余地方指过去就行。这一步能把上面几个例子的体积砍掉八成以上,而且不丢任何信息。

导航菜单为什么会出现在商品页的结构化数据里?

awaytravel的每一个商品页都带着82个SiteNavigationElement节点,8个页面一个不差。这是全样本里唯一出现这种类型的站。

schema.org对这个类型的定义是网页上的导航区块,用来描述站点结构。它本身是合法的,历史上也确实有过用途——早年Google的站内链接展示会参考这类标记。

但那个展示形式后来被下线了,这批标记现在既不产生任何搜索结果特征,也不帮助理解页面主体,只是每次加载都跟着走一遍。82个节点,占了那个页面全部节点的一半以上。

类似的还有WebSite加SearchAction那一组,57个页面写了。这一组当年是为站内搜索框准备的,那个特性同样已经不在了。

这批标记有个共同点:它们不是错的,只是它们服务的那个功能已经不存在了。删掉不会有任何损失,留着也不会被罚,于是就一直留着——14个不相干的站发着同一份给老浏览器的补丁是同一个道理,没人负责给这类东西定一个下线日期。

这类东西在结构化数据里格外容易囤积,因为它没有反馈。写错一个价格,前台会崩;多写82条导航,谁也不会知道,除非有人像这次一样把节点数出来。Schema官方第一次公开全网使用数据之后,判断该做哪些类型总算有了参照系,可判断该删哪些类型,仍然没有现成的清单。

这些Product节点是从哪儿长出来的?

2550个Product节点,按它们在JSON里的位置归类:

位置节点数是什么
hasVariant下2157ProductGroup展开的尺码与颜色
根节点445这一页真正在卖的那件
@graph里的hasVariant49同上,只是包了一层@graph
itemListElement.item18面包屑或列表里带出来的
其它31报价里的itemOffered、评分里的itemReviewed

八成半来自变体展开。这件事本身是Google在商品变体文档里明确推荐的做法:用ProductGroup加hasVariant把一组变体表达清楚,让搜索结果知道这件衣服有哪些颜色可选。

所以这不是错。要区分清楚:变体该不该有独立网址、canonical往哪儿指是另一个问题,WooCommerce那套三层治理讨论的也是网址与索引。这一篇不碰网址,只数节点——同一个决定,在网址那一层是收敛还是发散的选择题,在字节这一层是一道加法题。

展开到251个,还是不是那个推荐做法

rothys那双鞋展开了250个尺码节点。文档里的示例通常是几个到十几个变体,没有讨论过展开两百多个之后会怎样。

值得注意的是,这250个节点里没有一个写了名字、图片或描述,只有一个网址Google对商品结构化数据的字段要求里,name和image是拿到商品富媒体结果的底线。这批节点一个都不满足,它们进不了任何展示形式。

那它们的作用是什么?告诉机器这个ProductGroup有250个成员,各自的地址在哪。这个信息有价值,但用250个空壳节点来表达,代价是把这一页撑到232KB。

同一个站,热门款和长尾款的差距有多大?

每个站我都取了三件主推款和两件长尾款——按图片数加标签数排序,最多的和最少的。同一个站、同一套模板,唯一的变量是这件商品本身有多少东西可写。

分组页数字节中位节点中位没有Product节点的页
热门款1577767254
长尾款992325914

差3.3倍。51个能配成对的站里,43个是热门款更大,7个反过来,1个持平。

这个方向是符合直觉的:热门款变体多、评价多、图片多,写出来自然长。但它带来一个不太直觉的推论——你在自己站上抽查结构化数据的时候,如果只抽首页推荐的那几件,量到的数字会系统性地偏高;如果只抽最新上架的,又会系统性地偏低。

更值得留意的是最后一列。长尾款里有14页一个Product节点都没有,热门款只有4页。同一个站、同一套模板,长尾商品掉队的概率高出一截——这跟商品描述空值那次看到的方向一致:缺东西的商品,往往是被整体冷落的那一批。

这一条对做集合页与AI购物的人尤其要紧。主推款有完整标记、长尾款连Product节点都没有,意味着一个按品类问过来的购物代理,能看清的永远是你已经在卖爆的那几件。

有多少商品页干脆什么都不写?

392个页面里,12页一个ld+json标签都没有,占3.1%。23页有标签但没有任何Product节点,占5.9%。

零JSON-LD那批里,tentree是唯一一个整站如此的。我不太敢信这个结果——一个正经在卖货的品牌站,商品页一行结构化数据都不写,听起来更像是我没等到它渲染完。

所以我拿它单独复验了两轮。第一轮换成等网络空闲、再多等20秒,结果更糟:这个站压根等不到网络空闲,90秒超时,一个页面都没拿回来。第二轮改回等DOM就绪,把等待拉到22秒,中间滚动一次触发懒加载,同时查JSON-LD和微数据——三个不同的商品页全部200,script标签0个,itemtype元素0个,连一个h1都没有。这个站的商品页确实什么标记都没写。

顺带一说,第一轮失败本身也是条经验:等网络空闲这个条件在电商站上经常等不到,因为埋点和推荐组件会一直发请求。它看起来是更严谨的等待方式,实际更容易一无所获。

这件事的代价很直接:拿不到商品富媒体结果,进不了免费商品列表,AI购物代理读这一页的时候只能从纯文本里猜价格和库存。页面类型声明那次实测发现产品页的声明率有94%,tentree属于剩下那6%里最彻底的一种。

另外7个页面的JSON解析直接失败

这7页分布在4个站:graza占4页,untuckit、getquip、functionofbeauty各1页。它们的ld+json标签是有的,内容也在,但JSON.parse抛错——对搜索引擎来说,这跟没写是一个效果。

graza那4页的情况尤其值得说:它每页有5个ld+json标签,坏的只是其中1个,剩下4个能正常解析,所以在多数审计工具里这一页会显示为有结构化数据、字段齐全。一个尾逗号就能让整页结构化数据失效那篇讲的是单个标签内部的语法,这里补一条:一页有多个标签的时候,坏掉的那个通常是最晚注入的那个第三方应用,而不是主题自己输出的那份。

这类问题跟插件和主题各输出一套结构化数据是一条线上的两个症状:多方往同一个位置写东西,谁也不知道最终拼出来是什么样。区别在于那一篇处理的是内容打架,这里是其中一方直接写坏了语法。

我这把尺子量到的,是等了4秒之后的那一版

这一节讲我自己的口径问题,它比上面任何一个百分比都值得记。

主采集的流程是:打开页面,等DOM就绪,再等4秒,然后取JSON-LD。4秒这个数是抄的上一批参数,当时够用。

做自基线复验的时候,我把同一批网址重新跑了一遍,这次等22秒。三个页面里,两个的结果一模一样:rothys那双鞋两次都是237214字节,stanley那个保温杯两次都是118735字节。尺子是稳的。

第三个不一样。awaytravel那个旅行箱,第一次是5个script标签26518字节,第二次变成7个标签33785字节,多出来27%。多出来的那两个标签是异步注入的,4秒内没到。

页面等4秒等22秒差异
rothys平底鞋237214字节237214字节0
stanley保温杯118735字节118735字节0
awaytravel旅行箱26518字节33785字节+27%
brooklinen床品h1有0个h1有1个结论会反转

最后一行最要命:同一个页面,等得短一点,我会写下这个站的商品页没有h1;等得久一点,结论就反了。

这个坑的一般形式是:凡是异步注入的东西,你量到多少取决于你等了多久,而不同的读者等的时间不一样。我等4秒,Googlebot等多久没有公开数字,AI爬虫多数根本不执行JavaScript。AI爬虫抓不到JS渲染那次实测量的正是这个落差。

所以本文这批数字的正确读法是:它们是一个等了4秒的浏览器看到的版本,是下限。真实体积只会更大,而对不执行JavaScript的抓取方来说,真实体积只会更小。量出74%的页面对爬虫和用户不一样、补上对照组之后只剩2.2%那次的教训在这儿同样成立:任何一个跨页面的差异,先问它是不是自己抖出来的。

自己站上这份清单怎么数?

不用装工具,浏览器控制台一行就够:把页面上所有ld+json标签的内容拼起来看长度,再递归数一遍带@type的对象有多少个。数出来之后按下面四步走。

第一步:先看总量落在哪一档

拿本文那张分档表当基准。落在1到4KB是常态,超过10KB就该往下拆一层,看是哪种类型的节点在贡献数量。

第二步:按类型排序,找出现次数远超页面数的那几种

判据很简单:一个商品页需要几个Organization?一个。需要几份退货政策?一份。需要几条导航菜单?零条。凡是数量明显超出这个常识的类型,都是模板循环漏出来的。

第三步:把重复的对象改成引用

店铺信息、配送政策、退货政策、品牌,这四类在整页里应该只有一份实体,其余位置用@id指过去。这一步不改变任何语义,只减字节。

第四步:删掉那些没有对应展示形式的类型

SiteNavigationElement、WebSite加SearchAction这两组,现在都没有对应的搜索结果特征了。Google的结构化数据通用准则要求标记内容与页面主体相关,这两类跟商品页的主体没有关系。

一个反例:什么时候不该删

变体展开是唯一一类我建议先别动的。它虽然贡献了85%的Product节点,但确实在为商品变体展示服务。真要减,方向不是删节点,是给每个变体补上name和image让它们够格进展示,或者在变体数量特别多的时候只展开有代表性的那一批——两百多个尺码全展开,展示端也用不上。

怎么估这一步能省多少?拿本批的样本算给你看:stanley那个保温杯有42个变体,每个变体的报价里带一份卖家信息和一份退货政策。这两类各留一份、其余用引用,节点数从190掉到106左右,字节能砍掉一多半,而进入展示形式的字段一个没少——因为展示端读的是根节点那一份。保哥的判断标准很简单:一个对象在这一页里被完整写了两遍以上,它就该变成引用。

什么时候这套检查不该做

如果你的商品页JSON-LD在4KB以内、节点数在20以内,这件事的优先级很低,不值得排进这个季度。结构化数据里价格全写了、规格只有7个站写那种缺字段的问题,收益比减字节大得多。字节这一层只在两种情况下值得动手:整页已经逼近抓取的字节上限,或者你在做DOM元素数量那一类的整体瘦身,顺手一起做。

常见问题解答

商品页的结构化数据太大,Google会不会因此不收录?

不会因为体积本身不收录。但结构化数据是HTML的一部分,会计入整页字节,而抓取时读取的字节是有实际上限的。如果整页已经很大,这一块又占了几十KB,被截断的风险就是真实的。判断方法是先看整页体积落在哪个区间,再看这一块占了多少。

变体全部展开成Product节点,到底该不该做?

该做,这是官方推荐的表达方式。要注意的是两点:一是每个变体节点最好带上name和image,只有一个网址的空壳节点进不了任何展示形式;二是变体数量特别多的时候,全部展开的边际收益很低,把体积撑大的代价却是实打实的。

用@id引用代替复制,会不会影响搜索引擎理解?

不会。用引用把重复对象合成一份是JSON-LD的标准用法,解析方会把引用还原成同一个实体。真正需要注意的是@id的取值必须在整页内唯一且稳定,写错了才会出问题。

SiteNavigationElement现在还有用吗?

没有对应的搜索结果展示形式了。它不会被判为违规,但也不产生任何收益。放在首页可能还有一点表达站点结构的意义,放在每一个商品页上就纯粹是负担。

一页有多个ld+json标签,是不是也算问题?

数量本身不是问题,本批的中位数就是2个。要留意的是标签越多,其中一个语法出错而其余正常的概率越高,这种情况在多数审计工具里不会报出来。检查的时候要逐个标签解析,不能只看整页有没有结构化数据。

只统计JSON-LD会不会漏掉很多?

会。本批就有站把图集和问答全放在微数据里,JSON-LD一个字都没写。做自己站的审计时,五种格式都要扫一遍,否则容易得出错误结论。

怎么知道搜索引擎实际读到的是哪一版?

用能渲染的测试工具跑一遍,跟自己在浏览器里看到的对比。差异通常出在异步注入的第三方标记上——你等得久,它有;抓取方等得短,它没有。这一层的差异用肉眼在源码里是看不出来的。

权威参考资料

分享到
标签
版权声明

本文标题:《一张礼品卡的结构化数据119KB,同一段配送政策抄了60遍》

本文链接:https://zhangwenbao.com/product-page-jsonld-node-inventory-audit.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交