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 適合小型測試和報告。如果要定期追蹤排名、提醒、看板和歷史對比,建議使用資料庫。