关键词排名监控
定期抓取目标关键词在 Google 的有机排名,存入数据库,追踪排名变化趋势。这是 SEO 工具最核心的功能之一。
涉及 API
| API | 用途 |
|---|---|
| Google Organic Live Regular | 轻量抓取 Top 10,成本可控 |
| Google Organic Live Advanced | 需要 Featured Snippet、PAA 等完整 SERP 时 |
| Google Organic 异步任务 | 每日批量 100+ 词时使用 |
工作流
1. 维护关键词列表(DB / CSV)
2. 定时任务(cron)调用 SERP API
3. 解析 items[],找到目标域名的 rank_absolute
4. 写入 rank_history 表
5. 前端展示趋势图 / 告警完整 Python 示例(含 cron 友好结构)
import sqlite3
from datetime import date
import requests
API_KEY = "smt_live_YOUR_KEY"
BASE = "https://api.seermartech.cn/v3"
TARGET_DOMAIN = "mysite.com"
KEYWORDS = [
"SEO工具",
"关键词研究",
"外链分析",
# ... 最多数百个
]
def fetch_rank(keyword: str, location_code: int = 2156) -> dict | None:
resp = requests.post(
f"{BASE}/serp/google/organic/live/regular",
headers={"Authorization": f"Bearer {API_KEY}"},
json=[{
"keyword": keyword,
"location_code": location_code,
"language_code": "zh",
"device": "desktop",
"depth": 100,
}],
timeout=60,
)
resp.raise_for_status()
items = resp.json()["tasks"][0]["result"][0]["items"]
for item in items:
if item.get("type") != "organic":
continue
url = item.get("url", "")
if TARGET_DOMAIN in url:
return {
"keyword": keyword,
"rank": item.get("rank_absolute"),
"url": url,
"charge_cny": resp.headers.get("X-SeerMarTech-Charge-CNY"),
}
return {"keyword": keyword, "rank": None, "url": None}
def save_ranks(results: list):
conn = sqlite3.connect("rank_history.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS ranks (
date TEXT, keyword TEXT, rank INTEGER, url TEXT,
PRIMARY KEY (date, keyword)
)
""")
today = date.today().isoformat()
for r in results:
conn.execute(
"INSERT OR REPLACE INTO ranks VALUES (?, ?, ?, ?)",
(today, r["keyword"], r["rank"], r["url"]),
)
conn.commit()
conn.close()
if __name__ == "__main__":
results = [fetch_rank(kw) for kw in KEYWORDS]
save_ranks(results)
print(f"tracked {len(results)} keywords")cron 配置示例
# 每天 6:00 运行排名抓取
0 6 * * * /usr/bin/python3 /opt/seo/rank_tracker.py >> /var/log/rank_tracker.log 2>&1TypeScript(Node.js 定时任务)
const API_KEY = "smt_live_YOUR_KEY";
const TARGET_DOMAIN = "mysite.com";
async function fetchRank(keyword: string): Promise<{ keyword: string; rank: number | null }> {
const resp = await fetch(
"https://api.seermartech.cn/v3/serp/google/organic/live/regular",
{
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify([{
keyword,
location_code: 2156,
language_code: "zh",
device: "desktop",
depth: 100,
}]),
}
);
const data = await resp.json();
const items = data.tasks[0].result[0].items;
for (const item of items) {
if (item.type === "organic" && item.url?.includes(TARGET_DOMAIN)) {
return { keyword, rank: item.rank_absolute };
}
}
return { keyword, rank: null };
}成本估算
| 规模 | 模式 | 单次 cost | 日费用 | 月费用 |
|---|---|---|---|---|
| 50 词/天 | Live Regular | ≈ ¥0.032 | ≈ ¥1.60 | ≈ ¥48 |
| 100 词/天 | Live Regular | ≈ ¥0.032 | ≈ ¥3.20 | ≈ ¥96 |
| 500 词/天 | Standard Queue | ≈ ¥0.0096 | ≈ ¥4.80 | ≈ ¥144 |
| 1000 词/天 | Standard Queue | ≈ ¥0.0096 | ≈ ¥9.60 | ≈ ¥288 |
以上为参考价,实际以响应
cost为准。
最佳实践
- Regular vs Advanced:只需排名位置时用 Regular;需要 SERP 特征(精选摘要、广告)时用 Advanced
- depth 设置:监控 Top 50 排名设
depth: 50即可,不必默认 100,可节省约 50% cost - 批量切换:超过 50 词/天建议改用 异步任务模式
- 失败重试:上游偶发超时,建议单词失败重试 2 次,仍失败记为
rank: null - 余额监控:每次请求检查
X-SeerMarTech-Balance-CNY,低于阈值发告警,见 用量与成本控制