KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
04 · 结构化数据体系:从词汇表到实体图谱 — keel 龙骨
本章目标:把结构化数据从"给页面加几个标记",升级为"给站点建实体图谱"。 验收标准:站内实体的 @id 与 sameAs 自洽,富结果资格可验证、失效可排查。
本章目标:把结构化数据从"给页面加几个标记",升级为"给站点建实体图谱"。
验收标准:站内实体的@id与sameAs自洽,富结果资格可验证、失效可排查。
为什么要拔高:基础课讲了 JSON-LD 决定富结果资格。但在站点规模变大后,问题是同一个实体在多个页面上出现,引擎能不能认出它们是同一个。这就是实体图谱(Entity Graph)要解决的事,也是结构化数据的真正价值所在。
一、从词汇表到图:三层认知
| 层次 | 关注点 | 典型做法 |
|---|---|---|
| L1 词汇表 | 用对 @type 与字段 |
文章用 Article、面包屑用 BreadcrumbList |
| L2 实体声明 | 每个实体有稳定身份 | 给实体分配 @id |
| L3 实体图谱 | 实体间的引用与消歧 | 用 @id 互相引用、用 sameAs 对齐外部身份 |
大多数站点停留在 L1。L2/L3 才是能让引擎把散落在多页的信息拼成一个实体的关键。
二、@id:给实体一个稳定的身份
@id 是实体的规范标识(通常是一个 URL)。同一实体在不同页面用同一个 @id,引擎才能把它们合并。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"@id": "https://www.xxxxxx.cn/learning/authors/alice/#person",
"name": "Alice",
"jobTitle": "Backend Engineer"
}
</script>
在另一页引用同一个作者时,不要重复定义,直接引用 @id:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "抓取预算的量化",
"author": { "@id": "https://www.xxxxxx.cn/learning/authors/alice/#person" }
}
</script>
规则:
@id使用带片段(#)的绝对 URL,稳定不变。- 组织、作者、网站等核心实体,只在权威页面定义一次。
- 其余页面引用而非重定义。
三、sameAs:对齐外部身份(消歧)
sameAs 声明"这个实体在别处也是它",用于实体消歧——告诉引擎你的作者/组织与外部权威来源是同一个。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://www.xxxxxx.cn/#organization",
"name": "示例学习站",
"url": "https://www.xxxxxx.cn/",
"sameAs": [
"https://github.com/example-org",
"https://www.linkedin.com/company/example-org"
]
}
</script>
| 场景 | sameAs 指向 | 收益 |
|---|---|---|
| 组织 | 官方社交/代码托管主页 | 知识面板正确关联 |
| 作者 | 个人主页、其他平台档案 | 作者权威性可核对 |
| 产品 | 官方商城页 | 消歧,避免同名混淆 |
注意:sameAs 必须指向真实存在、且确实属于你的页面。指向无关页面属于欺骗性标记。
四、一个站点级图谱的最小结构
一个自洽的最小图谱包含三个核心实体,用 @id 串起来:
Organization (https://www.xxxxxx.cn/#organization)
└─ WebSite (https://www.xxxxxx.cn/#website)
└─ Article / Course (.../#article)
├─ author → Person (.../#person)
└─ breadcrumb → BreadcrumbList
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "Organization", "@id": "https://www.xxxxxx.cn/#organization",
"name": "示例学习站", "url": "https://www.xxxxxx.cn/" },
{ "@type": "WebSite", "@id": "https://www.xxxxxx.cn/#website",
"url": "https://www.xxxxxx.cn/",
"publisher": { "@id": "https://www.xxxxxx.cn/#organization" } },
{ "@type": "Article", "@id": "https://www.xxxxxx.cn/learning/courses/tools/lessons/1/#article",
"headline": "抓取预算的量化",
"isPartOf": { "@id": "https://www.xxxxxx.cn/#website" },
"author": { "@id": "https://www.xxxxxx.cn/#organization" } }
]
}
</script>
用 @graph 把相关实体放在一个脚本里,是最推荐的写法——它让引擎一次看到完整的关系。
五、富结果资格与失效排查
资格 ≠ 展示。合格只是"进入抽奖池"。排查失效按以下顺序:
| 排查项 | 方法 | 常见问题 |
|---|---|---|
| 语法合法 | JSON 解析器校验 | 尾逗号、注释混入 |
| 必填字段齐全 | 对照官方富结果文档 | 缺 datePublished 等 |
| 与可见内容一致 | 人工核对 | 标了评分但页面无评分 |
| 能否被渲染 | 检查是否 JS 注入 | 第一波拿不到 |
| 是否被手动处理 | GSC 的"增强功能/手动操作" | 欺骗性标记 |
| 是否满足内容质量 | 页面本身是否有价值 | 标记对但内容薄 |
# 抽取页面里的所有 JSON-LD 并逐个校验语法
curl -s https://www.xxxxxx.cn/learning/courses/tools/lessons/1/ \
| perl -0777 -ne 'while (/<script type="application\/ld\+json">(.*?)<\/script>/sg) {
my $j=$1; print "---\n$j\n"; }' > /tmp/ld.json
node -e "const t=require('fs').readFileSync('/tmp/ld.json','utf8');
t.split('---').filter(Boolean).forEach((s,i)=>{ try{JSON.parse(s);console.log(i,'OK')}
catch(e){console.log(i,'BAD',e.message)} });"
六、常见反模式
| 反模式 | 问题 | 修法 |
|---|---|---|
| 全站同一个 Article | 无法区分页面 | 每个内容页独立实体 |
| 每页重复定义 Organization | 图谱冗余、可能冲突 | 权威页定义,其余引用 |
@id 用相对路径或不稳定 URL |
实体无法稳定合并 | 用绝对 URL + 片段 |
| 标记与可见内容不一致 | 违规 | 删掉无支撑的字段 |
| 只在 JS 里注入 | 第一波不可见 | 服务端直出 |
| sameAs 指向无关站点 | 欺骗 | 只填真实归属 |
七、故障速查
| 现象 | 图谱层原因 | 处理 |
|---|---|---|
| 知识面板信息错误 | sameAs 缺失或错误 | 补正确的外部档案 |
| 富摘要不出现 | 语法/必填/一致性 | 按第五节顺序排查 |
| 实体被拆成多个 | @id 不统一 |
统一实体身份 |
| 增强功能报错 | 字段与内容不符 | 修正后重新验证 |
| 面包屑不显示 | BreadcrumbList 缺失 | 补标记并直出 |
八、本章验收
- 站内核心实体(组织/网站/作者)有稳定
@id且只定义一次 - 内容页引用实体而非重复定义
-
sameAs指向真实归属的外部页面 - 能抽取并校验页面 JSON-LD 语法
- 富结果失效时能按顺序排查到具体原因
# 本章核心:抽出所有 JSON-LD 校验语法
curl -s https://www.xxxxxx.cn/learning/ | grep -c 'application/ld+json'
实体层建好后,回到结构层:URL、内链与分页如何支撑发现与权重分配。