Yandex Search API:如何追踪俄罗斯与 CIS 市场排名
了解如何使用 Yandex Search API 追踪俄罗斯与 CIS 市场的关键词排名,通过 Python 按城市、国家、语言和设备采集本地化 SERP 数据,并导出为 CSV。
快速回答: Yandex Search API 可以帮助 SEO 团队以程序化方式采集 Yandex 搜索结果,按城市、国家、语言和设备追踪关键词排名,并把结果导出用于报告。当你的 SEO 工作面向俄罗斯或 CIS 市场时,这类排名数据很有价值。
如果你的 SEO 报告只追踪 Google,可能会漏掉俄罗斯及周边俄语或 CIS 市场中的重要搜索可见度。
Yandex 排名不应被视为 Google 排名的复制版。某个页面在 Google 表现很好,不代表它在 Yandex 中也有同样可见度。对 SEO 团队、代理商、平台型网站和国际品牌来说,Yandex 应该作为独立搜索渠道来追踪。
SERP API 可以让这件事更简单。你不需要从不同地区手动检查 Yandex 搜索结果,而是可以发送结构化请求,获取能被系统存储和分析的搜索结果。
我们要构建什么?
我们会建立一个 Python 流程:
关键词列表
→ 市场和语言列表
→ Yandex SERP API 请求
→ 提取自然搜索结果
→ 找出目标域名排名
→ 导出排名数据到 CSV
最终 CSV 可以包含:
|
字段 |
含义 |
|
|
搜索查询 |
|
|
目标市场标签 |
|
|
城市或地区 |
|
|
目标国家或市场 |
|
|
搜索语言 |
|
|
桌面或移动设备 |
|
|
目标域名排名位置 |
|
|
命中的排名 URL |
|
|
命中的页面标题 |
|
|
前排排名域名 |
|
|
采集时间 |
这套流程适合 Yandex SEO 报告、竞品监控、俄语 SEO、跨市场可见度检查和定期排名追踪。
为什么要单独追踪 Yandex 排名?
Yandex 不应被当成 Google 的另一个镜像。
在追踪俄罗斯与 CIS 市场 SEO 时,你可能需要比较:
|
维度 |
为什么重要 |
|
城市 |
排名可能因本地市场而变化 |
|
语言 |
俄语与本地语言查询可能返回不同结果 |
|
设备 |
移动设备和桌面版结果可能不同 |
|
关键词表述 |
翻译词不一定符合真实搜索习惯 |
|
竞品 |
本地竞品在 Yandex 可能比 Google 更可见 |
例如,下面两个查询应该分开追踪:
купить ноутбук
buy laptop
它们可能指向同一个商品类别,但代表不同用户行为、语言意图和搜索结果竞争环境。
Step 1:设置环境变量
不要把 API 密钥直接写进代码。
export TALORDATA_API_KEY="your_api_key_here"
export TALORDATA_SERP_ENDPOINT="your_talordata_serp_endpoint_here"
Windows PowerShell:
$env:TALORDATA_API_KEY="your_api_key_here"
$env:TALORDATA_SERP_ENDPOINT="your_talordata_serp_endpoint_here"
安装 Python 依赖:
pip install requests
Step 2:定义关键词和目标市场
先从一组小型测试数据开始。
KEYWORDS = [
"купить ноутбук",
"доставка цветов",
"онлайн курсы английского",
]
MARKETS = [
{
"market": "Russia - Moscow",
"location": "Moscow, Russia",
"country": "ru",
"language": "ru",
},
{
"market": "Kazakhstan - Almaty",
"location": "Almaty, Kazakhstan",
"country": "kz",
"language": "ru",
},
{
"market": "Belarus - Minsk",
"location": "Minsk, Belarus",
"country": "by",
"language": "ru",
},
]
TARGET_DOMAIN = "example.com"
DEVICE = "desktop"
正式使用时,请根据你的 SEO 策略换成真实关键词组、目标地区和语言设置。
Step 3:建立 SERP API 请求辅助函数
把请求层和解析逻辑分开。
import os
import requests
def require_env(name):
value = os.getenv(name)
if not value:
raise RuntimeError(f"Missing required environment variable: {name}")
return value
TALORDATA_API_KEY = require_env("TALORDATA_API_KEY")
TALORDATA_SERP_ENDPOINT = require_env("TALORDATA_SERP_ENDPOINT")
def call_serp_api(payload):
headers = {
"Authorization": f"Bearer {TALORDATA_API_KEY}",
"Content-Type": "application/json",
}
response = requests.post(
TALORDATA_SERP_ENDPOINT,
json=payload,
headers=headers,
timeout=30,
)
response.raise_for_status()
return response.json()
有些 API 使用 GET,也有些会把 API key 放在查询参数中。如果你的设置不同,只需要修改这个辅助函数。
Step 4:获取 Yandex SERP 结果
接着建立一个发送本地化 Yandex 搜索请求的函数。
def fetch_yandex_serp(keyword, location, country, language, device="desktop"):
payload = {
"engine": "yandex",
"q": keyword,
"location": location,
"gl": country,
"hl": language,
"device": device,
"num": 10,
"output": "json",
}
return call_serp_api(payload)
实际参数名称可能取决于你的 SERP API 设置。核心思路是:每次请求都要明确保存关键词、地区、国家、语言和设备。
Step 5:提取自然搜索结果
不同 SERP 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):
results = get_organic_results(serp_json)
rows = []
for index, item in enumerate(results, 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 6:找出目标域名排名
检查目标域名是否出现在前排结果中。
def find_domain_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"],
"matched_title": item["title"],
}
return {
"position": None,
"matched_url": "",
"matched_title": "",
}
def summarize_top_domains(results, limit=10):
domains = []
for item in results[:limit]:
if item["domain"]:
domains.append(item["domain"])
return " | ".join(domains)
如果没有找到目标域名,就把排名保留为 None,不要填入假排名。
Step 7:导出 Yandex 排名数据到 CSV
import csv
from datetime import datetime, timezone
CSV_COLUMNS = [
"keyword",
"market",
"location",
"country",
"language",
"device",
"target_domain",
"position",
"matched_url",
"matched_title",
"top_domains",
"collected_at",
]
def export_to_csv(rows, filename="yandex_rankings.csv"):
if not rows:
print("No ranking rows found.")
return
with open(filename, mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=CSV_COLUMNS)
writer.writeheader()
writer.writerows(rows)
print(f"Exported {len(rows)} ranking rows to {filename}")
完整 Python 示例
import os
import csv
import requests
from datetime import datetime, timezone
from urllib.parse import urlparse
KEYWORDS = [
"купить ноутбук",
"доставка цветов",
"онлайн курсы английского",
]
MARKETS = [
{
"market": "Russia - Moscow",
"location": "Moscow, Russia",
"country": "ru",
"language": "ru",
},
{
"market": "Kazakhstan - Almaty",
"location": "Almaty, Kazakhstan",
"country": "kz",
"language": "ru",
},
{
"market": "Belarus - Minsk",
"location": "Minsk, Belarus",
"country": "by",
"language": "ru",
},
]
TARGET_DOMAIN = "example.com"
DEVICE = "desktop"
CSV_COLUMNS = [
"keyword",
"market",
"location",
"country",
"language",
"device",
"target_domain",
"position",
"matched_url",
"matched_title",
"top_domains",
"collected_at",
]
def require_env(name):
value = os.getenv(name)
if not value:
raise RuntimeError(f"Missing required environment variable: {name}")
return value
TALORDATA_API_KEY = require_env("TALORDATA_API_KEY")
TALORDATA_SERP_ENDPOINT = require_env("TALORDATA_SERP_ENDPOINT")
def call_serp_api(payload):
headers = {
"Authorization": f"Bearer {TALORDATA_API_KEY}",
"Content-Type": "application/json",
}
response = requests.post(
TALORDATA_SERP_ENDPOINT,
json=payload,
headers=headers,
timeout=30,
)
response.raise_for_status()
return response.json()
def fetch_yandex_serp(keyword, location, country, language, device="desktop"):
payload = {
"engine": "yandex",
"q": keyword,
"location": location,
"gl": country,
"hl": language,
"device": device,
"num": 10,
"output": "json",
}
return call_serp_api(payload)
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):
results = get_organic_results(serp_json)
rows = []
for index, item in enumerate(results, 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
def find_domain_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"],
"matched_title": item["title"],
}
return {
"position": None,
"matched_url": "",
"matched_title": "",
}
def summarize_top_domains(results, limit=10):
domains = []
for item in results[:limit]:
if item["domain"]:
domains.append(item["domain"])
return " | ".join(domains)
def export_to_csv(rows, filename="yandex_rankings.csv"):
if not rows:
print("No ranking rows found.")
return
with open(filename, mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=CSV_COLUMNS)
writer.writeheader()
writer.writerows(rows)
print(f"Exported {len(rows)} ranking rows to {filename}")
if __name__ == "__main__":
collected_at = datetime.now(timezone.utc).isoformat()
output_rows = []
for keyword in KEYWORDS:
for market in MARKETS:
serp_json = fetch_yandex_serp(
keyword=keyword,
location=market["location"],
country=market["country"],
language=market["language"],
device=DEVICE,
)
organic_results = normalize_organic_results(serp_json)
ranking = find_domain_ranking(organic_results, TARGET_DOMAIN)
output_rows.append({
"keyword": keyword,
"market": market["market"],
"location": market["location"],
"country": market["country"],
"language": market["language"],
"device": DEVICE,
"target_domain": TARGET_DOMAIN,
"position": ranking["position"],
"matched_url": ranking["matched_url"],
"matched_title": ranking["matched_title"],
"top_domains": summarize_top_domains(organic_results),
"collected_at": collected_at,
})
export_to_csv(output_rows)
执行后会得到:
yandex_rankings.csv
输出示例
keyword,market,location,country,language,device,target_domain,position,matched_url,matched_title,top_domains,collected_at
купить ноутбук,Russia - Moscow,"Moscow, Russia",ru,ru,desktop,example.com,4,https://example.com/laptops,Example Laptop Store,domain1.ru | domain2.ru | example.com,2026-06-22T00:00:00Z
доставка цветов,Kazakhstan - Almaty,"Almaty, Kazakhstan",kz,ru,desktop,example.com,,,,domain3.kz | domain4.kz | domain5.kz,2026-06-22T00:00:00Z
如何使用输出结果?
Yandex SEO 报告可以按以下方式分组:
|
分组方式 |
可以看出什么 |
|
关键词 |
哪些查询有可见度 |
|
市场 |
哪些地区排名强或弱 |
|
语言 |
俄语或本地语言页面是否有排名 |
|
设备 |
桌面和移动设备是否存在差异 |
|
前排域名 |
哪些竞品最常出现 |
例如:
Keyword: доставка цветов
Moscow: position 5
Almaty: not found
Minsk: position 9
这可以帮你判断哪些地方需要优化本地化落地页、俄语内容、内部链接、商品页或区域相关性。
Best Practices
单独追踪 Yandex,不要假设 Google 排名等于 Yandex 排名。
使用真实本地关键词表述。直接翻译可能不符合用户实际搜索习惯。
每一行都保存市场、地区、语言、国家和设备,否则排名数据很难分析。
开发阶段保存原始 API 响应,方便排查字段缺失和搜索结果版面变化。
将自然搜索结果、广告、本地结果和特殊 SERP 模块分开标记,不要混在一起。
如果要定期追踪,后续应改用数据库。CSV 适合测试,但历史看板需要结构化存储。
FAQ
什么是 Yandex Search API?
Yandex Search API 可以让你以程序化方式采集 Yandex 搜索结果,适合 SEO 排名追踪、竞品监控、市场研究和本地化搜索分析。
为什么要追踪 Yandex 排名?
如果你的受众会使用 Yandex,只追踪 Google 可能会漏掉重要可见度变化。Yandex 排名应该作为独立渠道监控。
可以按城市和语言追踪排名吗?
可以。SERP API 可以根据供应商支持的选项,使用城市、国家、语言和设备参数发送本地化请求。
可以比较 Yandex 和 Google 排名吗?
可以。你可以用同一组关键词分别查询两个搜索引擎,并比较排名位置、前排域名、摘要和落地页。
Yandex 排名数据应该存成 CSV 还是数据库?
CSV 适合小型测试和报告。如果要定期追踪排名、提醒、看板和历史对比,建议使用数据库。