搜索 API 响应模块:featured_snippet、PAA 与 knowledge_graph 怎么用
大部分人调搜索 API 只取 organic 数组就收工,其实响应里还有一整层没被用起来:featured_snippet(精选摘要)、people_also_ask(别人还在问)、knowledge_graph(实体面板)、top_stories、related_searches------文档还提到 ai_overview、weather、finance、flight、result_stats 这些"出现在 SERP 上时才会返回"的模块。
这些模块对 SEO 和 GEO 的价值比 organic 更直接:精选摘要告诉你 Google 认为这个问题的标准答案是什么,PAA 直接给你用户真实问法,知识面板给你实体属性。这篇讲每个模块的用途和代码里怎么稳妥地取。字段口径以 SerpBase 官方文档的 search 端点字段表 为准;每次成功请求 1 credit。
先看清楚:模块全是可选的
文档对这些模块的定位很一致:除 organic 外都是可选字段,各自的说明都带"当解析到时才有"的意味------featured_snippet 是"单独于 organic 结果返回的摘要卡片",top_stories/knowledge_graph/related_searches 同理,并明确"当这些模块出现在 SERP 时"才会返回 ai_overview、weather、finance、flight、result_stats。
工程上的结论:所有模块都必须用 .get() 或 in 判断,一个都不能直取。零结果时不仅是 organic 可能缺,整个模块键都可能不存在。这也是为什么下面脚本里每个模块都单独判存在。
各模块的实战用途
| 模块 | 是什么 | 有什么用 |
|---|---|---|
featured_snippet |
精选摘要卡片,单独于 organic 返回 | 看 Google 选中的"标准答案",做内容对标 |
people_also_ask |
问题、答案、来源链接 | 挖用户真实问法,做 FAQ 和长尾词 |
knowledge_graph |
实体面板数据 | 品牌/产品的实体属性核对 |
top_stories |
新闻模块 | 时效性判断、舆情监测 |
related_searches |
相关搜索词 | 词库扩展 |
ai_overview |
AI 摘要(GEO 核心) | 看哪些词触发了 AI 摘要、引用了谁 |
对各模块逐一说明:精选摘要 是零点击搜索的核心,如果你的词有 featured_snippet 而你的站不在里面,那就是明确的内容机会;PAA 的每个问题都是真实的用户问法,比任何关键词工具都直接,而且带答案和来源链接,可以直接看 Google 引用了谁;AI 摘要是 GEO 战场,文档明确它在"出现在 SERP 时"才返回,所以要做 AI 引用监测,得把它当可选模块处理, gaps 就是常态。
模块采集脚本
python
import csv, json, requests
API = "https://api.serpbase.dev/google/search"
KEY = "你的 API Key"
HEADERS = {"X-API-Key": KEY, "Content-Type": "application/json"}
def serp(q: str, hl: str = "zh-CN", gl: str = "cn") -> dict:
resp = requests.post(API, headers=HEADERS,
json={"q": q, "hl": hl, "gl": gl}, timeout=30)
data = resp.json()
if data.get("status") != 0:
raise RuntimeError(f"{data.get('status')}: {data.get('error')}")
return data
def module_profile(data: dict) -> dict:
"""一次响应里到底有哪些模块,以及各模块的体量。"""
return {
"organic": len(data.get("organic", [])),
"featured_snippet": "featured_snippet" in data,
"paa_count": len(data.get("people_also_ask", [])),
"knowledge_graph": "knowledge_graph" in data,
"top_stories": len(data.get("top_stories", [])),
"related_searches": len(data.get("related_searches", [])),
"ai_overview": "ai_overview" in data,
}
if __name__ == "__main__":
queries = ["SERP API 是什么", "谷歌搜索 API 价格"]
rows = []
for q in queries:
data = serp(q)
profile = module_profile(data)
print(f"--- {q}: {json.dumps(profile, ensure_ascii=False)}")
# 精选摘要:单独于 organic 的卡片
fs = data.get("featured_snippet")
if fs:
rows.append({"query": q, "模块": "featured_snippet",
"内容": str(fs)[:200], "来源": ""})
# PAA:问题 + 答案 + 来源
for paa in data.get("people_also_ask", []):
rows.append({"query": q, "模块": "PAA",
"内容": paa.get("question", ""),
"来源": str(paa.get("source", ""))[:100]})
# 相关搜索:词库扩展
for rs in data.get("related_searches", []):
rows.append({"query": q, "模块": "related_searches",
"内容": rs, "来源": ""})
# AI 摘要:GEO 监测对象
if "ai_overview" in data:
rows.append({"query": q, "模块": "ai_overview",
"内容": str(data["ai_overview"])[:200], "来源": ""})
if rows:
with open("modules.csv", "w", newline="", encoding="utf-8-sig") as f:
w = csv.DictWriter(f, fieldnames=["query", "模块", "内容", "来源"])
w.writeheader()
w.writerows(rows)
print(f"共 {len(rows)} 条模块数据 → modules.csv")
跑一轮先看 module_profile 的输出,你会直观感受到两件事:一是不同查询词的模块构成差异极大(有的有精选摘要没 PAA,有的反过来);二是 ai_overview 的出现率比想象中低------这正是 GEO 监测要做填充率统计的原因。
三条实战经验
- PAA 的问题文本是最优质的长尾词来源。 它来自 Google 对真实查询的聚类,比关键词工具的"猜"准得多。做 FAQ 块或写文章时,直接把 PAA 问题当小标题,内容和 Google 已引用的答案形成差异,才有机会挤进去。
- featured_snippet 要单独存储,别混进 organic 排名逻辑。 它是独立卡片,不占 organic 位次;做排名监控时如果把它算进 organic,你的位次数据会整体偏移。分开统计,才能说清"有摘要卡"和"自然排名第几"是两回事。
- ai_overview 监测按周做,别按天。 它时有时无,日频采样的信噪比很低;按周采样 + 记录触发率,才能看出"哪些词的 AI 摘要开始引用竞品"这类真实变化。每次请求 1 credit,周频的成本可以忽略。
FAQ
organic 为空但其他模块有数据,算成功还是失败? 算成功。status 为 0 就说明请求成功了,只是这个 SERP 没有解析出自然结果------可能被其他模块占满(比如纯知识面板查询)。按空 organic 处理,模块数据照取。
related_searches 是字符串数组还是对象? 文档写的是"相关搜索查询"的数组,通常形态是字符串;脚本里按可迭代处理,遇到对象形态时取其中的查询文本字段即可,以实际返回为准。
这些模块会影响计费吗? 不会。search 端点固定 1 credit 一次,模块多少不影响价格------这也让"多取模块"成为纯赚:同样的钱,取回来的信息量差好几倍。
ai_overview 的字段结构文档写了吗? 文档只说"当模块出现在 SERP 时"会返回,没给详细字段表;脚本里对不明确结构的模块统一用 str() 截断存储,以实际返回为准,不猜字段名。
把 module_profile 加进你现有的采集流程------它会让你第一次看清:同一个 API 调用,你原来只用了三分之一。