Google 搜索 API:从搜索查询到结构化 JSON
Advanced Data Extraction Specialist
TL;DR:
- 无废品的 Google 搜索 API 以结构化 JSON 的形式返回搜索结果。 在研究工具、SEO 报告和源发现工作流程中使用自然结果字段。
- 搜索上下文与结果密切相关。 将查询、国家、语言和观察时间放在一起,以便后续比较具有明确的意义。
- 待处理任务与空结果集不同。 在尝试读取
organic_results或创建 CSV 之前,请单独处理 HTTP 201。
当团队能够将每个结果与产生该结果的问题和市场连接时,Google 搜索数据就变得有用。复制到电子表格中的标题和 URL 丧失了许多上下文。结构化响应使应用程序从一开始就能够保留这些信息。
更新后的 无废品 Google 搜索 API 提供了一条从搜索查询到 JSON 的管理路径。您的应用程序发送请求,并决定如何使用返回的数据。代理和 CAPTCHA 处理在服务端运行,减少了您的团队需要维护的采集基础设施。
本指南遵循该交接:选择搜索上下文,提交请求,读取响应,并保存另一个人可以理解的数据集。
Google 搜索 API 返回的内容
Google 搜索 API 返回结构化搜索数据,当存在时,自然结果可在顶级 organic_results 数组中找到。自然结果可以包括 position、title、link 和 snippet。响应还可以包含分页信息和其他搜索模块,具体取决于查询和返回的结果。
在提取子集之前,请保留原始响应。扁平表格便于分析,但无法在没有故意映射的情况下表示每个嵌套对象。JSON 数据模型 区分数组、对象、字符串、数字、布尔值和 null;保留这些区别可以使后续处理更加容易。
片段是搜索结果的摘录。它不提供目标页面的完整内容。如果研究应用需要文章的证据,应用程序必须单独获取和审查该页面。
准备一个小的首次请求
首次请求需要一个无废品 API 密钥、一个查询和一个能够通过 HTTP 发送 JSON 的客户端。使用可以访问 Google 搜索 API 的帐户,并将密钥保存在 SCRAPELESS_API_KEY 环境变量中。
在下面的 Python 示例中,在您的项目环境中安装 requests 包。其余模块来自 Python 的标准库。将脚本保存为 google_search_export.py,然后在通过本地 shell 或密钥管理器设置环境变量后,用 python3 google_search_export.py 运行它。
该示例使用中立的查询 coffee、国家 us 和语言 en。在引入关键字列表或计划作业之前,请先使用此小输入。首先检查响应的形状;下游数据模型依赖于此。
经过认证的请求是需要您自己帐户密钥的前提条件。该示例的请求形状遵循当前 API 参考;没有以捕获的实时帐户运行的形式呈现。
选择国家、语言和输入模式
国家、语言和位置描述搜索请求的不同部分。gl 选择搜索国家,hl 选择搜索语言,location 指定搜索应该从何处发起。google_domain 选择 Google 域名。当前设备选项支持桌面。
Google 搜索 API 参数模型 还有两个输入规则,影响您构造请求的方式:
- 使用
q作为通过单个参数表达的查询。或者,提供完整的 Google 搜索url;当提供url时,其他输入参数将被忽略。 - 选择
location或uule。这两者不能一起使用。
为了跨市场进行比较,请保存每个响应的完整输入对象。设置相同的国家和语言使预期上下文明确,但不能保证在观察之间结果相同,也不能重现特定人员的登录搜索历史。
查询可以包括操作符,例如 site:、inurl: 和 intitle:。使用它们来缩小研究问题。 站点限制搜索 并不是索引页面的完整清单,因此其结果不应成为确切的索引覆盖计数。
请求 JSON 和导出自然结果
请求使用 POST https://api.scrapeless.com/api/v1/scraper/request、scraper.google.search 参与者和 x-api-token 头。该脚本在 HTTP 200 后保存响应及其输入和接收时间,然后将自然结果导出为 CSV。
注意:网络请求需要您的 Scrapeless API 密钥,并且未使用此文章的实时帐户执行。该脚本保留了 HTTP 201 任务响应以供检查;它不实现任务结果的检索。
python
import csv
import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
def spreadsheet_text(value):
text = "" if value is None else str(value)
if text.lstrip().startswith(("=", "+", "-", "@")) or text.startswith(("\t", "\r")):
return "'" + text
return text
def export_results(payload, context, received_at, output_path):
results = payload.get("organic_results")
if not isinstance(results, list):
print("No usable organic_results array; inspect the saved JSON.")
return
fields = ["q", "gl", "hl", "received_at", "position", "title", "link", "snippet"]
with output_path.open("w", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=fields)
writer.writeheader()
for item in results:
if not isinstance(item, dict):
raise ValueError("Unexpected organic result item; inspect the saved JSON.")
row = {name: item.get(name) for name in ("position", "title", "link", "snippet")}
row.update(context, received_at=received_at)
writer.writerow({name: spreadsheet_text(row.get(name)) for name in fields})
print(f"Exported {len(results)} organic results to {output_path}")
def main():
context = {"q": "coffee", "gl": "us", "hl": "en"}
response = requests.post(
"https://api.scrapeless.com/api/v1/scraper/request",
headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]},
json={"actor": "scraper.google.search", "input": context},
timeout=120,
)
response.raise_for_status()
received_at = datetime.now(timezone.utc).isoformat()
run_id = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
payload = response.json()
record = {"input": context, "received_at": received_at,
"http_status": response.status_code, "response": payload}
output = Path(f"google-search-{run_id}.json")
output.write_text(json.dumps(record, ensure_ascii=False, indent=2), encoding="utf-8")
if response.status_code == 201:
print(f"Task pending. Inspect taskId in {output}; no CSV was created.")
return
if response.status_code != 200 or not isinstance(payload, dict):
raise ValueError(f"Unexpected response; inspect {output}")
export_results(payload, context, received_at, output.with_suffix(".csv"))
if __name__ == "__main__":
main()
在此示例中,120 超时是客户端设置,而不是服务响应时间承诺。接收时间由客户端在响应到达后记录;这不是 Google 提供的时间戳。
Python 的 CSV 写入器 处理定界符和带引号的字段。该助手还在导出的文本前添加常见电子表格公式标记。保留 JSON 作为原始记录,因为 CSV 是为了检查而转换的视图。在外部来源的值在电子表格中打开之前,检查文本导入设置。
该示例仅导出其输入中的 q、gl 和 hl。如果您添加位置、域名或分页偏移,请扩展 CSV 列以保留那些维度。保存的 JSON 已包含完整的输入对象。
在构建报告之前解释响应
HTTP 200 响应包含任务数据,而 HTTP 201 表示正在处理并提供 taskId。挂起的任务不应产生空结果观察。该脚本保留其 JSON 记录,并在这种情况下跳过 CSV 导出。
对于成功的数据响应,区分空数组与缺失或不可用的 organic_results 字段。其他模块可能仍然存在。该脚本保留响应并要求您在没有可用数组时检查它。
将 position 视为提供的返回结果的位置。在将页面组合成全局排名之前,验证该端点如何为您的请求编号。start 控制结果偏移,分页信息可以指导后续请求;两者都无法确定每个 Google 结果都可以被检索。
将结构化搜索数据付诸实践
结构化搜索结果为您的应用围绕 API 构建的工作流提供输入。有用的单元是结果及其请求上下文和观察时间。
- SEO 快照: 保存固定关键字列表的观察,然后随时间比较匹配上下文。调度、存储和变化检测属于您的管道。
- 品牌和竞争对手研究: 审查选定查询中哪些域名和页面标题出现。该示例描述了这些搜索,而不是所有的网络提及或某个网站的流量。
- AI 源发现: 将候选标题、链接和片段传递到源选择步骤。当需要证据时,单独获取完整页面,并检查生成的声明是否与其来源相符。
对于内容团队,第一个输出可能是附有查询和市场的简短阅读列表。对于开发人员,它可能是现有报告中使用的可重复导出。两者都以数据记录开始,使其范围可见。
使用这些示例来收集和使用您被允许的公共信息。保留任务所需的字段,保护凭证,并检查适用于下游重用的条件。
结论
Google Search API 使应用程序能够使用结构化搜索数据。有用的集成还保留输入,检查任务状态,并将源发现与后续分析分开。从单一查询开始,并在扩展工作流之前检查保存的 JSON。
更新的 Google Search API 请求工作流 提供了将此示例调整为您自己项目的连接详细信息。
常见问题
问:这是 Google 提供的 API 吗?
本文描述了 Scrapeless Google Search API,这是一个用于检索 Google 搜索数据的 Scrapeless 服务。这并不声称与 Google 有正式合作关系。
问:需要管理浏览器或代理吗?
管理 API 在服务端处理收集基础设施。您的客户端发送 HTTP 请求并处理返回的数据。
问:API 是否包括历史排名数据?
所描述的工作流程通过保存您自己的观察来创造历史。它不会检索预先存在的排名历史。
问:同一个API可以搜索图片吗?
该产品支持Google图片搜索,在参数参考中标识了tbm=isch。请单独检查图像响应;本文的CSV映射用于自然网络结果。
问:搜索摘要包含完整页面吗?
摘要是与搜索结果相关的摘录。需要页面完整证据的工作流程必须单独获取和审查目标内容。
问:当请求返回HTTP 201时应该发生什么?
保留taskId并将任务视为待处理。在将其处理为完成的搜索数据之前,完成记录的任务结果工作流程。
在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。



