JSON-LD标记优化进阶:从基础到高级的标记实战与调试技巧
上一篇讲了Schema的7种类型,这篇深入讲JSON-LD本身。同样一个Article标记,新手写的和高手写的差别巨大——嵌套是否合理、字段是否完整、数据是否动态同步、错误处理是否到位。这些细节决定了富媒体结果能不能稳定触发。
我审过几百个站的JSON-LD,发现90%的站都停留在”能跑就行”的阶段,标记覆盖率不到40%,字段完整度不到60%。优化到位后,富媒体触发率能翻倍。
JSON-LD的核心逻辑
JSON-LD本质是一段JSON数据,通过@context声明词汇表(schema.org),用@type声明内容类型,其余字段就是内容属性。
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "JSON-LD标记优化进阶",
"datePublished": "2024-09-01"
}
关键理解:JSON-LD不是HTML的一部分,它是独立的数据层。搜索引擎读这段JSON来理解页面内容。所以它的结构和HTML结构无关,只和内容逻辑有关。
为什么JSON-LD碾压Microdata
我做个对比你就明白了:
<!-- Microdata写法:侵入HTML,维护噩梦 -->
<div itemscope itemtype="https://schema.org/Article">
<h1 itemprop="headline">JSON-LD标记优化进阶</h1>
<span itemprop="datePublished">2024-09-01</span>
<div itemprop="author" itemscope itemtype="https://schema.org/Person">
<span itemprop="name">张三</span>
</div>
</div>
<!-- JSON-LD写法:干净分离 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "JSON-LD标记优化进阶",
"datePublished": "2024-09-01",
"author": {
"@type": "Person",
"name": "张三"
}
}
</script>
JSON-LD和内容完全解耦,改内容不动标记,改标记不动内容。动态生成也方便,后端模板渲染时把变量填进去就行。
嵌套结构:把关联数据打包
JSON-LD最强大的能力是嵌套。一个Article可以嵌套Author、Publisher、Review,一个Product可以嵌套Offer、AggregateRating、Brand。嵌套让数据关联更清晰,搜索引擎理解更准确。
标准嵌套模板
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "JSON-LD标记优化进阶",
"description": "深入讲解JSON-LD的嵌套、动态生成、调试技巧",
"image": {
"@type": "ImageObject",
"url": "https://example.com/jsonld-guide.jpg",
"width": 1200,
"height": 675
},
"author": {
"@type": "Person",
"name": "张三",
"url": "https://example.com/author/zhangsan",
"jobTitle": "SEO技术专家",
"sameAs": [
"https://twitter.com/zhangsan",
"https://linkedin.com/in/zhangsan"
]
},
"publisher": {
"@type": "Organization",
"name": "某科技博客",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png",
"width": 200,
"height": 60
}
},
"datePublished": "2024-09-01",
"dateModified": "2024-09-15",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/jsonld-guide"
},
"about": {
"@type": "Thing",
"name": "结构化数据标记"
}
}
</script>
这个模板覆盖了Article的所有关键字段。重点说几个容易被忽略的:
image要带width和height,Google要求至少1200x675author的sameAs链接到社交媒体,强化作者权威性mainEntityOfPage声明页面主题,告诉搜索引擎这是关于什么的dateModified必填,Google用它判断内容新鲜度
动态生成:和CMS数据打通
静态写死的JSON-LD维护成本高,正确做法是后端动态生成。我以Python为例展示怎么和CMS数据打通。
import json
from datetime import datetime
def generate_article_schema(article):
# 根据文章数据生成JSON-LD
schema = {
"@context": "https://schema.org",
"@type": "Article",
"headline": article["title"],
"description": article["summary"],
"image": {
"@type": "ImageObject",
"url": article["cover_image"],
"width": 1200,
"height": 675
},
"author": {
"@type": "Person",
"name": article["author_name"],
"url": "https://example.com/author/" + article["author_slug"]
},
"publisher": {
"@type": "Organization",
"name": "某科技博客",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"datePublished": article["publish_date"].strftime("%Y-%m-%d"),
"dateModified": article["update_date"].strftime("%Y-%m-%d") if article.get("update_date") else article["publish_date"].strftime("%Y-%m-%d"),
"mainEntityOfPage": {
"@type": "WebPage",
"@id": article["canonical_url"]
}
}
# 有评论时加aggregateRating
if article.get("reviews"):
ratings = [r["rating"] for r in article["reviews"]]
schema["aggregateRating"] = {
"@type": "AggregateRating",
"ratingValue": round(sum(ratings) / len(ratings), 1),
"reviewCount": len(ratings),
"bestRating": 5,
"worstRating": 1
}
return json.dumps(schema, ensure_ascii=False)
这个函数把文章数据自动转成JSON-LD,新文章发布即生成标记,零维护成本。关键是数据源要准确——publish_date、author_name、cover_image这些字段在CMS里必须规范填写。
多类型组合:一个页面多种Schema
一个页面可以有多种Schema,比如产品页同时有Product、BreadcrumbList、FAQ。正确做法是用@graph数组组织。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Product",
"name": "人体工学椅",
"offers": {
"@type": "Offer",
"price": "1299",
"priceCurrency": "CNY"
}
},
{
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "首页"
},
{
"@type": "ListItem",
"position": 2,
"name": "办公家具"
}
]
},
{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "保修期多久?",
"acceptedAnswer": {
"@type": "Answer",
"text": "提供5年质保,框架终身保修。"
}
}
]
}
]
}
</script>
@graph让多个Schema共存且互不干扰,搜索引擎能分别解析。这比写多个<script>标签更规范。
字段优先级:哪些必须填,哪些可选
JSON-LD字段分三档:必需、推荐、可选。填错优先级要么被警告,要么白费功夫。
| 字段级别 | 含义 | 后果 |
|---|---|---|
| required(必需) | Google强制要求 | 缺失则富媒体不触发 |
| recommended(推荐) | 强烈建议填 | 缺失影响展示效果 |
| optional(可选) | 锦上添花 | 填了更好,不填无碍 |
以Article为例:
- 必需:headline、author、datePublished、image、publisher
- 推荐:dateModified、description、mainEntityOfPage
- 可选:about、keywords、articleBody
必需字段缺一个,整个富媒体就不触发。我审过很多站,问题90%是缺必需字段。
调试和验证流程
JSON-LD写完不验证就上线,等于裸奔。我的标准验证流程:
步骤1:语法验证
用Python的json模块先验证JSON语法是否合法。一个逗号错了整段失效。
# 本地验证语法
import json
schema_json = '{"@context": "https://schema.org", ...}'
try:
parsed = json.loads(schema_json)
print("语法正确")
except json.JSONDecodeError as e:
print("语法错误: " + str(e))
步骤2:Google Rich Results Test
把URL或代码粘贴到Google Rich Results Test,它会告诉你:
- 标记是否被识别
- 触发哪种富媒体结果
- 缺少哪些必需字段
- 有哪些警告
步骤3:Search Console监测
上线后在Search Console的”增强功能”里监测。这里能看到全站的标记覆盖情况、错误数、警告数。有问题及时修。
常见错误和修复
我处理过的JSON-LD错误,最常见的是这5类:
错误1:URL用了相对路径
所有URL字段必须用绝对路径(带https://)。/images/logo.png这种相对路径Google不认。
错误2:日期格式不规范
必须用ISO 8601格式:2024-09-01或2024-09-01T08:00:00+08:00。写2024年9月1日直接失效。
错误3:数字字段传了字符串
price字段必须是数字类型1299,不能是字符串"1299"。ratingValue同理。
错误4:嵌套层级混乱
Author应该嵌套在Article里,而不是平铺在外层。嵌套结构要符合schema.org的定义。
错误5:重复标记同一内容
一个页面同一个Schema只出现一次。有人Article标记写了3遍,搜索引擎只认第一个,还可能判违规。
避坑清单
JSON-LD优化的核心避坑点:
- 别用生成器偷懒:在线生成器只适合测试,生产环境必须动态生成,保证数据同步
- 别标记页面没有的内容:Schema数据必须和页面可见内容一致,否则判违规
- 别忽视百度:百度对JSON-LD支持有限,国内站要同时用百度结构化数据平台提交
- 别一次性全站上线:先在测试环境验证,再灰度发布,最后全量
- 别忘记持续维护:内容更新时Schema要同步更新,过期数据会被搜索引擎降权
- 别只做Google:Bing、百度、搜狗都要考虑,字段要求有差异
JSON-LD是SEO技术里最”实”的部分,做了就有效果,效果可量化。把标记做到位,富媒体触发率上去,CTR自然提升。这套东西不难,难在细心和持续维护。