Local SEO SERP API:如何按城市和语言追踪排名
了解如何使用 SERP API 进行本地 SEO 排名追踪,按城市、国家、语言和设备采集搜索结果,并保存排名快照用于本地 SEO 报告。
本地 SEO 排名追踪很容易变复杂。
同一个网站,可能在一个城市排名很好,在另一个城市完全看不到。同一个关键词,也可能因国家、语言、设备,甚至本地搜索意图不同而出现不同结果。对代理商、连锁品牌、本地落地页团队和平台型网站来说,一份全国平均排名报告通常不够。
本地 SEO 需要带有地理上下文的 SERP 数据。
SERP API 可以用程序化方式采集搜索结果,让你按城市、语言、国家和设备追踪排名,而不是手动从不同地区查 Google。
快速回答
要追踪本地 SEO 排名,可以针对每个关键词和目标市场发送 SERP API 请求,并带上城市、国家、语言和设备参数。然后提取自然搜索结果,匹配目标域名,保存排名位置,并按时间比较排名快照。
实际流程通常是:
关键词列表
→ 城市和语言列表
→ SERP API 请求
→ 提取自然搜索结果
→ 匹配目标域名
→ 保存排名快照
→ 按城市和语言比较变化
为什么城市级排名很重要?
本地 SEO 不只是看网站有没有排名,而是看它在哪里有排名。
例如:
Keyword: emergency plumber
City: Austin
Language: English
和下面这组条件可能看到不同结果:
Keyword: emergency plumber
City: Dallas
Language: English
语言还会再增加一层差异:
Keyword: dentist near me
City: Miami
Language: English
Keyword: dentista cerca de mí
City: Miami
Language: Spanish
如果报告只显示一个平均排名,就可能把重要的本地差异藏起来。城市级报告可以帮你看清哪些地区可见度强,哪些落地页较弱,哪些市场被竞品抢走了。
本地排名追踪应该采集哪些数据?
一条有用的本地排名数据,不应该只有关键词和排名。
|
字段 |
为什么重要 |
|
|
被追踪的查询 |
|
|
要监控的网站 |
|
|
城市或本地市场 |
|
|
国家市场上下文 |
|
|
搜索语言 |
|
|
Desktop 或 mobile |
|
|
自然搜索排名 |
|
|
实际排名页面 |
|
|
搜索结果标题 |
|
|
可见摘要 |
|
|
用于历史比较的时间戳 |
没有 location、language、device 和 timestamp,排名数字很容易被误读。
New York mobile 搜索中的第 4 名,不等于 Chicago desktop 搜索中的第 4 名。
自然搜索排名 vs Local Pack 排名
本地 SEO 通常不只看一种结果类型。
|
结果类型 |
可以说明什么 |
|
自然搜索结果 |
哪些页面出现在标准网页结果中 |
|
Local Pack |
哪些商家出现在地图型本地结果中 |
|
Maps 结果 |
商家资料在地图搜索中的排名 |
|
Ads |
哪些竞品正在付费获取可见度 |
|
People Also Ask |
本地用户常问哪些问题 |
|
Shopping 结果 |
本地商业查询下出现哪些商品和商家 |
本文重点是自然搜索排名,但同一套数据结构也可以延伸到 Maps 或 Local Pack。Talordata 的 SEO monitoring 页面也描述了本地 SEO 监控场景,包括 map rankings、business profiles、ratings、reviews 和 local visibility data。
Step 1:准备关键词和地区
先从少量关键词和城市开始。
KEYWORDS = [
"emergency plumber",
"dentist near me",
"coffee shop",
]
LOCATIONS = [
{
"city": "Austin",
"country": "us",
"language": "en",
"location": "Austin, Texas, United States",
"device": "desktop",
},
{
"city": "Dallas",
"country": "us",
"language": "en",
"location": "Dallas, Texas, United States",
"device": "desktop",
},
{
"city": "Miami",
"country": "us",
"language": "es",
"location": "Miami, Florida, United States",
"device": "mobile",
},
]
TARGET_DOMAIN = "example.com"
正式使用时,可以把这些配置放在数据库或表格中。每一行代表一个追踪组合:
keyword + city + country + language + device
这个组合就是你的 rank tracking unit。
Step 2:发送本地化 SERP API 请求
把请求层和解析层分开,后面会更好维护。查看完整文档>>
import os
import requests
SERP_API_KEY = os.getenv("TALORDATA_API_KEY")
SERP_ENDPOINT = os.getenv("TALORDATA_SERP_ENDPOINT")
def call_serp_api(payload):
if not SERP_API_KEY:
raise RuntimeError("Missing TALORDATA_API_KEY")
headers = {
"Authorization": f"Bearer {SERP_API_KEY}",
"Content-Type": "application/json",
}
response = requests.post(
SERP_ENDPOINT,
json=payload,
headers=headers,
timeout=30,
)
response.raise_for_status()
return response.json()
def fetch_local_serp(keyword, location_config):
payload = {
"engine": "google",
"q": keyword,
"gl": location_config["country"],
"hl": location_config["language"],
"location": location_config["location"],
"device": location_config["device"],
"num": 10,
"output": "json",
}
return call_serp_api(payload)
重点不是变量名称,而是每次请求都要带上本地上下文。
Step 3:提取自然搜索结果
不同 API 或搜索类型可能使用不同字段,所以解析器要保持弹性。
from urllib.parse import urlparse
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.", "")
def get_organic_results(serp_json):
return (
serp_json.get("organic_results")
or serp_json.get("organic")
or serp_json.get("results")
or []
)
def normalize_organic_results(serp_json):
rows = []
for index, item in enumerate(get_organic_results(serp_json), start=1):
url = item.get("link") or item.get("url") or ""
rows.append({
"position": item.get("position") or item.get("rank") or index,
"title": clean_text(item.get("title")),
"url": url,
"domain": get_domain(url),
"snippet": clean_text(item.get("snippet") or item.get("description")),
})
return rows
这样每个城市和语言返回的结果都能整理成同一种格式。
Step 4:匹配目标域名
排名追踪要回答的问题很直接:
目标域名有没有出现在这个本地 SERP 里?排第几?
def find_target_ranking(results, target_domain):
target = target_domain.replace("www.", "").lower()
for item in results:
domain = item["domain"].lower()
if domain == target or domain.endswith("." + target):
return {
"position": item["position"],
"matched_url": item["url"],
"title": item["title"],
"snippet": item["snippet"],
}
return {
"position": None,
"matched_url": "",
"title": "",
"snippet": "",
}
如果没有找到目标域名,保留 None。不要偷偷改成 99 或 100,除非你的报表系统明确定义了这个规则。
Step 5:保存本地排名快照
第一版用 CSV 就够。
import csv
from datetime import datetime, timezone
CSV_COLUMNS = [
"keyword",
"target_domain",
"city",
"country",
"language",
"location",
"device",
"position",
"matched_url",
"title",
"snippet",
"collected_at",
]
def export_rankings(rows, filename="local_seo_rankings.csv"):
with open(filename, mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=CSV_COLUMNS)
writer.writeheader()
writer.writerows(rows)
def run_local_rank_tracking():
collected_at = datetime.now(timezone.utc).isoformat()
output_rows = []
for keyword in KEYWORDS:
for location_config in LOCATIONS:
serp_json = fetch_local_serp(keyword, location_config)
organic_results = normalize_organic_results(serp_json)
ranking = find_target_ranking(organic_results, TARGET_DOMAIN)
output_rows.append({
"keyword": keyword,
"target_domain": TARGET_DOMAIN,
"city": location_config["city"],
"country": location_config["country"],
"language": location_config["language"],
"location": location_config["location"],
"device": location_config["device"],
"position": ranking["position"],
"matched_url": ranking["matched_url"],
"title": ranking["title"],
"snippet": ranking["snippet"],
"collected_at": collected_at,
})
export_rankings(output_rows)
if __name__ == "__main__":
run_local_rank_tracking()
每天跑一次,就能累积本地排名历史。
如何使用这些排名数据?
有了排名快照后,就能回答更有价值的问题。
|
问题 |
怎么看 |
|
哪些城市较弱? |
按 city 分组,比较平均排名 |
|
哪些页面在本地排名? |
按 |
|
哪种语言表现更好? |
比较 English、Spanish、French 或其他语言数据 |
|
哪些地区排名下跌? |
比较今天和昨天的快照 |
|
哪些关键词需要本地页面? |
找出目标城市中没有排名的关键词 |
|
Mobile 和 desktop 是否不同? |
比较 device 字段 |
这会让本地 SEO 从猜测变成可重复的报告流程。
什么时候该用数据库?
CSV 适合测试。
一旦 workflow 定期执行,就应该改用数据库。
一张简单数据表可以包含:
|
字段 |
类型 |
|
|
UUID 或 integer |
|
|
Text |
|
|
Text |
|
|
Text |
|
|
Text |
|
|
Text |
|
|
Text |
|
|
Integer 或 null |
|
|
Text |
|
|
Timestamp |
之后可以做本地 SEO 看板、排名提醒、城市对比报告、连锁门店可见度报告或每周 SEO 摘要。
Best practices
固定追踪同一组 keyword 和 location 组合。频繁变更追踪范围,会让趋势失真。
每一行都保存 city、country、language、device 和 timestamp。没有上下文的本地排名数据没有太多价值。
自然搜索、Maps、Local Pack、Ads 和 Shopping 要分开。它们应该进入不同报告。
开发阶段保存原始 API 响应。这有助于排查 parser 问题和 SERP feature 变化。
不要过度追踪稳定关键词。对多数本地 SEO 来说,每日追踪已经足够。高频追踪更适合重要发布或波动市场。
使用本地语言查询。不要只翻译界面语言,真实搜索行为可能和字面翻译不同。
FAQ
什么是用于本地 SEO 的 SERP API?
它是一种可以按关键词、地区、语言、国家和设备程序化采集搜索结果的 API,适合用于大规模追踪本地排名。
为什么要按城市追踪排名?
Google 搜索结果可能因城市而变化。同一个业务在一个市场排名很好,在另一个市场可能排名很弱。
为什么语言会影响本地 SEO 追踪?
搜索语言会影响查询意图、结果标题、摘要和排名页面。在多语市场,只追踪一种语言可能会漏掉可见度缺口。
Desktop 和 mobile 要分开追踪吗?
要。Desktop 和 mobile SERP 可能不同。应把 device 作为独立字段保存,避免报告混合不同搜索上下文。
这个流程可以追踪 Google Maps 排名吗?
可以,但 Maps 排名应该和自然搜索排名分开解析和报告。Local Pack 和 Maps 回答的问题,与标准网页结果不同。
CSV 足够做本地 SEO 排名追踪吗?
CSV 适合原型和小型报告。如果要做定期追踪、提醒、历史趋势和看板,建议使用数据库。