竞品监控不能靠手工,也不能只靠第三方工具。我搭了一套基于搜索API的竞品监控系统,每天自动追踪对手的新内容、排名变化、SERP特征变化。这篇文章分享完整架构。
一、竞品监控维度
python
COMPETITOR_MONITORING_DIMENSIONS = {
"rankings": {
"frequency": "daily",
"metrics": ["rank", "title", "snippet", "features"]
},
"new_content": {
"frequency": "daily",
"metrics": ["new_urls", "content_type", "publish_date"]
},
"schema_changes": {
"frequency": "weekly",
"metrics": ["schema_types", "rich_results"]
},
"backlink_signals": {
"frequency": "weekly",
"metrics": ["new_referrers", "lost_referrers"]
},
"social_signals": {
"frequency": "weekly",
"metrics": ["reddit_mentions", "twitter_mentions"]
}
}
二、核心监控引擎
2.1 排名监控
python
class CompetitorMonitor:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.serpbase.dev/google/search"
self.db = sqlite3.connect("competitor_monitor.db")
self._init_db()
def _init_db(self):
self.db.executescript("""
CREATE TABLE IF NOT EXISTS competitor_rankings (
date TEXT,
competitor TEXT,
keyword TEXT,
rank INTEGER,
title TEXT,
snippet TEXT,
url TEXT,
PRIMARY KEY (date, competitor, keyword)
);
CREATE TABLE IF NOT EXISTS competitor_content (
date TEXT,
competitor TEXT,
url TEXT,
title TEXT,
first_seen TEXT,
content_type TEXT,
PRIMARY KEY (date, competitor, url)
);
""")
def track_rankings(self, competitor: str, keywords: List[str]):
"""追踪竞品排名"""
today = datetime.now().strftime("%Y-%m-%d")
for keyword in keywords:
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
body = {
"q": keyword,
"hl": "en",
"gl": "us",
"page": 1
}
r = requests.post(self.base_url, headers=headers, json=body, timeout=30)
data = r.json()
for item in data.get("organic", []):
if competitor in item.get("link", ""):
self.db.execute("""
INSERT OR REPLACE INTO competitor_rankings
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
today, competitor, keyword, item["rank"],
item.get("title", ""), item.get("snippet", ""),
item.get("link", "")
))
self.db.commit()
2.2 新内容发现
python
def discover_new_content(self, competitor: str, api_key: str):
"""发现竞品新内容"""
# 用site:查询最近的内容
queries = [
f"site:{competitor}",
f"site:{competitor} 2026",
f"site:{competitor} guide",
f"site:{competitor} review"
]
new_pages = []
for query in queries:
headers = {
"X-API-Key": api_key,
"Content-Type": "application/json"
}
body = {
"q": query,
"hl": "en",
"gl": "us",
"page": 1
}
r = requests.post(self.base_url, headers=headers, json=body, timeout=30)
data = r.json()
for item in data.get("organic", []):
url = item.get("link", "")
# 检查是否已记录
existing = self.db.execute(
"SELECT 1 FROM competitor_content WHERE url = ?",
(url,)
).fetchone()
if not existing:
new_pages.append({
"url": url,
"title": item.get("title", ""),
"first_seen": datetime.now().isoformat(),
"content_type": self._detect_content_type(item.get("title", ""))
})
# 存入新内容
for page in new_pages:
self.db.execute("""
INSERT INTO competitor_content VALUES (?, ?, ?, ?, ?, ?)
""", (
datetime.now().strftime("%Y-%m-%d"),
competitor, page["url"], page["title"],
page["first_seen"], page["content_type"]
))
self.db.commit()
return new_pages
def _detect_content_type(self, title: str) -> str:
title_lower = title.lower()
if any(w in title_lower for w in ["how to", "guide", "tutorial"]):
return "guide"
elif any(w in title_lower for w in ["best", "top", "vs"]):
return "listicle"
elif "review" in title_lower:
return "review"
return "article"
三、告警系统
python
def check_alerts(self, competitor: str) -> List[Dict]:
"""检查竞品异常变化"""
alerts = []
# 1. 排名突增告警
recent = pd.read_sql(f"""
SELECT keyword, rank,
LAG(rank) OVER (PARTITION BY keyword ORDER BY date) as prev_rank
FROM competitor_rankings
WHERE competitor = '{competitor}'
AND date >= date('now', '-7 days')
ORDER BY date DESC
""", self.db)
for _, row in recent.iterrows():
if row['prev_rank'] and row['prev_rank'] - row['rank'] >= 5:
alerts.append({
"type": "rank_surge",
"competitor": competitor,
"keyword": row['keyword'],
"old_rank": row['prev_rank'],
"new_rank": row['rank'],
"severity": "high"
})
# 2. 新内容告警
new_content = pd.read_sql(f"""
SELECT * FROM competitor_content
WHERE competitor = '{competitor}'
AND first_seen >= date('now', '-3 days')
""", self.db)
if len(new_content) > 3:
alerts.append({
"type": "content_surge",
"competitor": competitor,
"new_pages": len(new_content),
"severity": "medium"
})
return alerts
四、竞品对比报告
python
def generate_competitor_report(self, competitor: str, days: int = 30) -> Dict:
"""生成竞品分析报告"""
# 排名变化
rankings = pd.read_sql(f"""
SELECT keyword, AVG(rank) as avg_rank
FROM competitor_rankings
WHERE competitor = '{competitor}'
AND date >= date('now', '-{days} days')
GROUP BY keyword
ORDER BY avg_rank
""", self.db)
# 新内容
new_content = pd.read_sql(f"""
SELECT url, title, content_type, first_seen
FROM competitor_content
WHERE competitor = '{competitor}'
AND first_seen >= date('now', '-{days} days')
ORDER BY first_seen DESC
""", self.db)
return {
"competitor": competitor,
"period_days": days,
"avg_rankings": rankings.to_dict(),
"new_content_count": len(new_content),
"new_content": new_content.to_dict(),
"content_strategy": self._analyze_content_strategy(new_content),
"recommendation": self._generate_recommendations(rankings, new_content)
}
def _analyze_content_strategy(self, new_content: pd.DataFrame) -> str:
types = new_content['content_type'].value_counts()
dominant = types.index[0] if len(types) > 0 else "unknown"
strategies = {
"guide": "Focus on educational content",
"listicle": "Focus on comparison content",
"review": "Focus on product reviews"
}
return strategies.get(dominant, "Mixed strategy")
五、总结
竞品监控的核心:
- 自动化:每天自动采集,不需要人工
- 多维度:排名、内容、Schema、外链
- 告警:异常变化立即通知
- 报告:定期生成分析报告
- 行动:基于数据制定反击策略
竞品监控不是偷窥,是学习。对手在做什么、什么有效,这些数据帮你少走弯路。用SerpBase做竞品监控的成本很低------监控5个竞品×50个关键词×30天=7,500次查询,成本$2.25。比买Semrush便宜100倍。