先看现象。面包屑用 ::after 输出分隔符,结构化数据脚本按 DOM 里的 span 数量计数,把分隔符也当成一级。itemListElement 里多出一条 name 为空的记录,整段校验失败。
真正麻烦的地方在于,几个原因的现象几乎一样。生成脚本按子元素个数计算 position 分隔符被算进去。也可能是分隔符是伪元素 无法用选择器排除。
不容易想到的是,position 出现跳号 从 1 直接跳到 3。
还有一种情况,最后一级没有 item 也被计入列表。
上来先导出结构化数据看层级
curl -s https://www.example.com/p/1 | grep -o 'itemListElement[^]]*'
随后改成按链接数量生成 position
$items = $dom->query('nav.breadcrumb a');
接着分隔符改用背景图 不占用元素
.breadcrumb li + li::before { content: ''; background: url(/img/sep.svg); }
剩下的就是重新跑一次结构化校验
curl -s 'https://validator.schema.org/#url=https://www.example.com/p/1'
手上没有现成的复现脚本,就照着线上请求手工拼了一个。
怎么算真的好了,看的是同一批现象。itemListElement 的 position 连续且每级都有 name,校验工具返回通过。
提醒一点。生成结构化数据时按数据源计数,不要按渲染后的 DOM 节点数计数。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
