结构化数据(JSON-LD)实战:让搜索引擎真正读懂你的文章
用 JSON-LD 把文章语义喂给搜索引擎,手把手实现 Article、BreadcrumbList 与 WebSite 三层结构化数据,附 Go 模板代码与验证工具。
搜索引擎能抓取你的页面,但它不一定读懂了。HTML 是给浏览器渲染的,它告诉引擎"这有段文字",却无法区分这段文字是文章标题、作者姓名还是价格。结构化数据(Structured Data)填补这个缺口:它用机器友好的格式,把"这是一篇技术文章、作者是张三、发布于 2026-06-15"明确传达给爬虫。
Google、Bing 和其他主流引擎都支持 Schema.org 词汇表,而 JSON-LD(JSON for Linked Data)是注入这套词汇最干净的方式。
为什么选 JSON-LD 而不是 Microdata / RDFa
三种格式都能表达结构化数据,但 JSON-LD 的工程优势明显:
- 与 HTML 解耦:以
<script type="application/ld+json">独立注入,不需要改动任何现有标签。 - 模板友好:服务端渲染时只需在
<head>里输出一段 JSON,逻辑集中。 - 可读性强:JSON 而非属性散落在 DOM 里,审查、调试都方便。
- Google 官方推荐:文档里明确标注 JSON-LD 为首选格式。
最小可用:Article 类型
对于技术博客,最常用的是 Article(或子类 TechArticle)。最小有效负载如下:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "结构化数据(JSON-LD)实战:让搜索引擎真正读懂你的文章",
"datePublished": "2026-06-15T08:00:00+08:00",
"dateModified": "2026-06-15T08:00:00+08:00",
"author": {
"@type": "Person",
"name": "CCVAR"
}
}
</script>
这已经够 Google 识别文章发布日期,让它在搜索结果里正确显示时效性标签。
逐步增强:完整的文章 Schema
完整版补上图片、摘要、出版者,以及让 Google 的"丰富结果"(Rich Results)能够展示:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "结构化数据(JSON-LD)实战:让搜索引擎真正读懂你的文章",
"description": "用 JSON-LD 把文章语义喂给搜索引擎,手把手实现 Article、BreadcrumbList 与 Site 三层结构化数据。",
"image": "https://ccvar.com/assets/og/json-ld-seo.png",
"datePublished": "2026-06-15T08:00:00+08:00",
"dateModified": "2026-06-15T08:00:00+08:00",
"author": {
"@type": "Person",
"name": "CCVAR",
"url": "https://ccvar.com"
},
"publisher": {
"@type": "Organization",
"name": "CCVAR 简记",
"logo": {
"@type": "ImageObject",
"url": "https://ccvar.com/assets/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://ccvar.com/zh/posts/json-ld-structured-data-seo"
}
}
</script>
mainEntityOfPage 是关键:它用 @id 把这段结构化数据锚定到具体 URL,帮引擎建立"这段 JSON 描述的正是当前页面"的关联。
面包屑导航(BreadcrumbList)
面包屑是最容易被忽视却立竿见影的类型。它直接影响搜索结果的 URL 展示方式——Google 会把面包屑替换默认的 URL 显示,让条目更易理解。
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "首页",
"item": "https://ccvar.com"
},
{
"@type": "ListItem",
"position": 2,
"name": "文章",
"item": "https://ccvar.com/zh/posts"
},
{
"@type": "ListItem",
"position": 3,
"name": "结构化数据(JSON-LD)实战",
"item": "https://ccvar.com/zh/posts/json-ld-structured-data-seo"
}
]
}
</script>
一个页面可以放多个 <script type="application/ld+json"> 块,引擎会各自解析,互不干扰。
站点级:WebSite 与 SearchAction
在首页放置 WebSite 类型,可以让 Google 在搜索结果里展示站内搜索框(Sitelinks Searchbox):
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "CCVAR 简记",
"url": "https://ccvar.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://ccvar.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
</script>
注意 potentialAction 只在首页放一次即可,文章页不需要重复。
用 Go 的服务端模板生成 JSON-LD
如果站点用 Go 驱动,可以直接在模板里构造结构化数据,避免手拼 JSON:
// schema.go
package schema
import (
"encoding/json"
"html/template"
"time"
)
type Article struct {
Context string `json:"@context"`
Type string `json:"@type"`
Headline string `json:"headline"`
Description string `json:"description"`
Image string `json:"image,omitempty"`
DatePublished time.Time `json:"datePublished"`
DateModified time.Time `json:"dateModified"`
Author Person `json:"author"`
Publisher Org `json:"publisher"`
MainEntityURL string `json:"mainEntityOfPage,omitempty"`
}
type Person struct {
Type string `json:"@type"`
Name string `json:"name"`
URL string `json:"url,omitempty"`
}
type Org struct {
Type string `json:"@type"`
Name string `json:"name"`
Logo Logo `json:"logo"`
}
type Logo struct {
Type string `json:"@type"`
URL string `json:"url"`
}
// ArticleLD 返回可直接嵌入模板的 JSON 字符串
func ArticleLD(post Post, siteURL string) (template.HTML, error) {
a := Article{
Context: "https://schema.org",
Type: "TechArticle",
Headline: post.Title,
Description: post.Excerpt,
Image: post.OGImage,
DatePublished: post.PublishedAt,
DateModified: post.UpdatedAt,
Author: Person{Type: "Person", Name: post.AuthorName, URL: siteURL},
Publisher: Org{
Type: "Organization",
Name: "CCVAR 简记",
Logo: Logo{Type: "ImageObject", URL: siteURL + "/assets/logo.png"},
},
MainEntityURL: siteURL + post.URL,
}
b, err := json.Marshal(a)
if err != nil {
return "", err
}
return template.HTML(string(b)), nil
}
在 Go 模板里调用:
{{- $ld := articleLD .Post .SiteURL -}}
<script type="application/ld+json">{{ $ld }}</script>
template.HTML 告诉 Go 模板引擎不要转义这段内容,JSON 里的 " 会被正确输出而不是变成 "。
验证:Rich Results Test
写完后必须验证,不然很可能字段缺失或类型写错而不自知:
- 打开 Rich Results Test
- 输入页面 URL(或直接粘贴 HTML 代码片段)
- 检查每个类型是否被识别,查看警告和错误
常见问题:
datePublished格式错误(必须是 ISO 8601,如2026-06-15T08:00:00+08:00,不能只写日期)image尺寸不足(Article 要求至少 1200×630px)headline超过 110 字符(AMP 场景下 Google 会截断并给出警告)
另一个工具是 Schema Markup Validator,它基于 Schema.org 规范而非 Google 子集,覆盖面更广。
什么不值得做
结构化数据不是 SEO 银弹,有几点不要迷信:
- 不能直接提升排名:Google 明确声明结构化数据不是排名信号,它影响的是展示方式(Rich Results),不是位置。
- 不要标注页面上没有的内容:比如给没有作者信息的页面强行加
author,这违反 Google 的垃圾内容政策,可能导致手动处置。 - 不要重复冗余字段:
description和meta description内容相同没问题,但别试图塞进所有 Schema 字段——只填你真正拥有的数据。
核心原则:结构化数据的价值在于准确描述页面内容,而非堆砌字段刷存在感。引擎足够聪明,会识别不一致和虚假标注。
小结
JSON-LD 的工程成本极低——本质上就是在 <head> 里多一段 JSON——但它能让搜索引擎更精准地理解你的页面,并在合适场景下展示富结果。对于内容站来说,TechArticle + BreadcrumbList + 首页 WebSite 这三层基本覆盖了所有高价值场景,用服务端模板统一生成,维护成本接近零。