如何將 SERP API 結果匯出到 Google Sheets
了解如何使用 Python 將 SERP API 結果匯出到 Google Sheets,包含搜尋結果抓取、title、link、snippet、ranking、metadata 提取,以及自動寫入試算表。
Google Sheets 通常是查看 SERP data 最簡單的地方。
一開始你不一定需要完整 database。如果團隊只是想查看 rankings、比較 domains、審核 snippets,或把搜尋結果分享給 SEO、產品、內容團隊,spreadsheet 通常已經足夠。
整體流程很簡單:
SERP API request
→ Receive SERP JSON
→ Extract titles, links, snippets, positions, and metadata
→ Append rows to Google Sheets
這篇文章會示範如何用 Python 將 SERP API results 匯出到 Google Sheets。範例保持 provider-neutral,所以可以改成 Talordata、SerpApi、Serper.dev、Bright Data、SearchAPI 或其他返回 structured JSON 的 SERP API。
應該匯出哪些 SERP Data?
多數 workflow 可以先從 organic search results 開始。你不需要把 raw response 裡所有欄位都匯出。
一份實用 spreadsheet 通常包含:
|
欄位 |
含義 |
|---|---|
|
|
搜尋 keyword |
|
|
Google、Bing、Yandex、DuckDuckGo 等 |
|
|
搜尋國家、地區或城市 |
|
|
Desktop 或 mobile |
|
|
排名位置 |
|
|
搜尋結果標題 |
|
|
目標 URL |
|
|
提取出的 domain |
|
|
搜尋結果摘要 |
|
|
資料收集時間 |
這個結構適合 SEO rank tracking、competitor monitoring、brand visibility check 和 AI source discovery。
Step 1:安裝 Python 套件
需要安裝三個 package:
pip install requests gspread google-auth
requests 用來調用 SERP API。gspread 用來寫入 Google Sheets。google-auth 用來處理 Google service account authentication。
Step 2:準備 Google Sheets 權限
建立一個 Google Sheet,並建立名為 SERP Results 的 tab。
接著建立 Google Cloud service account,下載 JSON credentials file,並把你的 Google Sheet 分享給 service account email。
專案資料夾可以像這樣:
project/
export_serp_to_sheets.py
service_account.json
不要把 service_account.json 上傳到 GitHub 或任何公開 repository。
Step 3:請求 SERP API Results
不同 SERP API 的 endpoint 會不同,下面範例保持通用。
import os
import requests
SERP_API_KEY = os.getenv("SERP_API_KEY")
SERP_API_ENDPOINT = os.getenv("SERP_API_ENDPOINT")
def fetch_serp_results(query, location="United States", device="desktop"):
params = {
"engine": "google",
"query": query,
"location": location,
"device": device,
"output": "json"
}
headers = {
"Authorization": f"Bearer {SERP_API_KEY}"
}
response = requests.get(
SERP_API_ENDPOINT,
params=params,
headers=headers,
timeout=30
)
response.raise_for_status()
return response.json()
有些 API 使用 q 而不是 query,有些把 API key 放在 query parameter,而不是 authorization header。建議將 API request 和 parsing logic 分開,這樣更換 provider 時不會影響 Google Sheets 寫入邏輯。
Step 4:Normalize SERP JSON
不同 SERP API 的欄位命名可能不同。有些返回 link,有些返回 url;有些返回 snippet,有些返回 description。
更穩定的做法是寫一個兼容型 parser。
from urllib.parse import urlparse
from datetime import datetime, timezone
def clean_text(value):
if not value:
return ""
return " ".join(str(value).split())
def get_domain(url):
if not url:
return ""
parsed = urlparse(url)
return parsed.netloc.replace("www.", "") if parsed.netloc else ""
def extract_organic_results(serp_json, query, location, device):
organic_results = serp_json.get("organic_results", [])
collected_at = datetime.now(timezone.utc).isoformat()
rows = []
for index, item in enumerate(organic_results, start=1):
link = item.get("link") or item.get("url")
if not link:
continue
rows.append([
query,
serp_json.get("search_parameters", {}).get("engine", "google"),
location,
device,
item.get("position") or index,
clean_text(item.get("title")),
link,
get_domain(link),
clean_text(item.get("snippet") or item.get("description")),
collected_at
])
return rows
這個 function 會按照 spreadsheet columns 的順序返回 rows。
Step 5:Append Rows 到 Google Sheets
接著連接 Google Sheets,將 rows 寫入表格。
import gspread
from google.oauth2.service_account import Credentials
GOOGLE_SHEET_NAME = "SERP API Results"
WORKSHEET_NAME = "SERP Results"
SERVICE_ACCOUNT_FILE = "service_account.json"
def get_worksheet():
scopes = [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive"
]
credentials = Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE,
scopes=scopes
)
client = gspread.authorize(credentials)
spreadsheet = client.open(GOOGLE_SHEET_NAME)
return spreadsheet.worksheet(WORKSHEET_NAME)
def append_rows_to_sheet(rows):
if not rows:
print("No rows to append.")
return
worksheet = get_worksheet()
worksheet.append_rows(rows, value_input_option="RAW")
print(f"Appended {len(rows)} rows.")
寫入前,可以先在表格中建立 header row:
query | engine | location | device | position | title | link | domain | snippet | collected_at
完整程式碼
import os
import requests
import gspread
from urllib.parse import urlparse
from datetime import datetime, timezone
from google.oauth2.service_account import Credentials
SERP_API_KEY = os.getenv("SERP_API_KEY")
SERP_API_ENDPOINT = os.getenv("SERP_API_ENDPOINT")
GOOGLE_SHEET_NAME = "SERP API Results"
WORKSHEET_NAME = "SERP Results"
SERVICE_ACCOUNT_FILE = "service_account.json"
def clean_text(value):
if not value:
return ""
return " ".join(str(value).split())
def get_domain(url):
if not url:
return ""
parsed = urlparse(url)
return parsed.netloc.replace("www.", "") if parsed.netloc else ""
def fetch_serp_results(query, location="United States", device="desktop"):
params = {
"engine": "google",
"query": query,
"location": location,
"device": device,
"output": "json"
}
headers = {
"Authorization": f"Bearer {SERP_API_KEY}"
}
response = requests.get(
SERP_API_ENDPOINT,
params=params,
headers=headers,
timeout=30
)
response.raise_for_status()
return response.json()
def extract_organic_results(serp_json, query, location, device):
organic_results = serp_json.get("organic_results", [])
collected_at = datetime.now(timezone.utc).isoformat()
rows = []
for index, item in enumerate(organic_results, start=1):
link = item.get("link") or item.get("url")
if not link:
continue
rows.append([
query,
serp_json.get("search_parameters", {}).get("engine", "google"),
location,
device,
item.get("position") or index,
clean_text(item.get("title")),
link,
get_domain(link),
clean_text(item.get("snippet") or item.get("description")),
collected_at
])
return rows
def get_worksheet():
scopes = [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive"
]
credentials = Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE,
scopes=scopes
)
client = gspread.authorize(credentials)
spreadsheet = client.open(GOOGLE_SHEET_NAME)
return spreadsheet.worksheet(WORKSHEET_NAME)
def append_rows_to_sheet(rows):
if not rows:
print("No rows to append.")
return
worksheet = get_worksheet()
worksheet.append_rows(rows, value_input_option="RAW")
print(f"Appended {len(rows)} rows.")
if __name__ == "__main__":
query = "best project management software"
location = "United States"
device = "desktop"
serp_json = fetch_serp_results(query, location, device)
rows = extract_organic_results(serp_json, query, location, device)
append_rows_to_sheet(rows)
Talordata 和其他 SERP API 適合放在哪裡?
這套 workflow 適用於任何返回 structured JSON 的 SERP API。
如果只是快速 Google-only prototype,Serper.dev 或 SerpApi 可能比較容易開始。如果是較大的 data collection workflow,團隊可能會比較 Bright Data、SearchAPI 或 DataForSEO。
如果你需要 structured SERP results、JSON / HTML output、geo-targeted searches,以及 Google、Bing、Yandex、DuckDuckGo 等多搜尋引擎支持,Talordata 值得測試(開始免費測試1000次API請求)。當 Google Sheets 只是第一步,後續還要進 dashboard、AI Agent 或 monitoring system 時,這類能力會更有用。
實際測試方式很簡單:用同一批 queries 跑 2–3 個 API,把結果匯出到同一張 sheet,再比較 field completeness、missing URLs、localization quality 和 cost per usable row。
常見使用場景
SEO Rank Tracking
把 SERP data 匯出到 Google Sheets,可以讓團隊在還沒搭建 dashboard 前就開始查看 ranking position。
Competitor Monitoring
你可以按 domain 分組,追蹤哪些 competitors 出現在重要 keywords 下。
Content Research
內容團隊可以先查看 titles、snippets 和 ranking URLs,再規劃新內容。
AI Agent Source Discovery
AI Agent 可以把 spreadsheet rows 當作輕量 source list,再決定是否抓取完整頁面。
FAQ
可以自動將 SERP API results 匯出到 Google Sheets 嗎?
可以。你可以用 Python 調用 SERP API,解析 JSON response,然後透過 Google Sheets API 或 gspread 將 rows 寫入 Google Sheets。
應該匯出哪些 SERP 欄位?
建議先匯出 query、engine、location、device、position、title、link、domain、snippet 和 timestamp。這些欄位適合 SEO、competitor monitoring 和 AI source discovery。
一定需要 database 嗎?
不一定。Google Sheets 適合測試、小型報告和團隊 review。如果是大規模長期 monitoring,database 會更合適。