竞品监控不能靠手工也不能只靠第三方工具。我搭了一套基于搜索API的竞品监控系统每天自动追踪对手的新内容、排名变化、SERP特征变化。这篇文章分享完整架构。一、竞品监控维度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 排名监控classCompetitorMonitor:def__init__(self,api_key:str):self.api_keyapi_key self.base_urlhttps://api.serpbase.dev/google/searchself.dbsqlite3.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) ); )deftrack_rankings(self,competitor:str,keywords:List[str]):追踪竞品排名todaydatetime.now().strftime(%Y-%m-%d)forkeywordinkeywords:headers{X-API-Key:self.api_key,Content-Type:application/json}body{q:keyword,hl:en,gl:us,page:1}rrequests.post(self.base_url,headersheaders,jsonbody,timeout30)datar.json()foritemindata.get(organic,[]):ifcompetitorinitem.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 新内容发现defdiscover_new_content(self,competitor:str,api_key:str):发现竞品新内容# 用site:查询最近的内容queries[fsite:{competitor},fsite:{competitor}2026,fsite:{competitor}guide,fsite:{competitor}review]new_pages[]forqueryinqueries:headers{X-API-Key:api_key,Content-Type:application/json}body{q:query,hl:en,gl:us,page:1}rrequests.post(self.base_url,headersheaders,jsonbody,timeout30)datar.json()foritemindata.get(organic,[]):urlitem.get(link,)# 检查是否已记录existingself.db.execute(SELECT 1 FROM competitor_content WHERE url ?,(url,)).fetchone()ifnotexisting:new_pages.append({url:url,title:item.get(title,),first_seen:datetime.now().isoformat(),content_type:self._detect_content_type(item.get(title,))})# 存入新内容forpageinnew_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()returnnew_pagesdef_detect_content_type(self,title:str)-str:title_lowertitle.lower()ifany(wintitle_lowerforwin[how to,guide,tutorial]):returnguideelifany(wintitle_lowerforwin[best,top,vs]):returnlisticleelifreviewintitle_lower:returnreviewreturnarticle三、告警系统defcheck_alerts(self,competitor:str)-List[Dict]:检查竞品异常变化alerts[]# 1. 排名突增告警recentpd.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_,rowinrecent.iterrows():ifrow[prev_rank]androw[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_contentpd.read_sql(f SELECT * FROM competitor_content WHERE competitor {competitor} AND first_seen date(now, -3 days) ,self.db)iflen(new_content)3:alerts.append({type:content_surge,competitor:competitor,new_pages:len(new_content),severity:medium})returnalerts四、竞品对比报告defgenerate_competitor_report(self,competitor:str,days:int30)-Dict:生成竞品分析报告# 排名变化rankingspd.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_contentpd.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:typesnew_content[content_type].value_counts()dominanttypes.index[0]iflen(types)0elseunknownstrategies{guide:Focus on educational content,listicle:Focus on comparison content,review:Focus on product reviews}returnstrategies.get(dominant,Mixed strategy)五、总结竞品监控的核心自动化每天自动采集不需要人工多维度排名、内容、Schema、外链告警异常变化立即通知报告定期生成分析报告行动基于数据制定反击策略竞品监控不是偷窥是学习。对手在做什么、什么有效这些数据帮你少走弯路。用SerpBase做竞品监控的成本很低——监控5个竞品×50个关键词×30天7,500次查询成本$2.25。比买Semrush便宜100倍。
搜索API驱动的竞品监控:7×24小时跟踪对手一举一动
竞品监控不能靠手工也不能只靠第三方工具。我搭了一套基于搜索API的竞品监控系统每天自动追踪对手的新内容、排名变化、SERP特征变化。这篇文章分享完整架构。一、竞品监控维度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 排名监控classCompetitorMonitor:def__init__(self,api_key:str):self.api_keyapi_key self.base_urlhttps://api.serpbase.dev/google/searchself.dbsqlite3.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) ); )deftrack_rankings(self,competitor:str,keywords:List[str]):追踪竞品排名todaydatetime.now().strftime(%Y-%m-%d)forkeywordinkeywords:headers{X-API-Key:self.api_key,Content-Type:application/json}body{q:keyword,hl:en,gl:us,page:1}rrequests.post(self.base_url,headersheaders,jsonbody,timeout30)datar.json()foritemindata.get(organic,[]):ifcompetitorinitem.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 新内容发现defdiscover_new_content(self,competitor:str,api_key:str):发现竞品新内容# 用site:查询最近的内容queries[fsite:{competitor},fsite:{competitor}2026,fsite:{competitor}guide,fsite:{competitor}review]new_pages[]forqueryinqueries:headers{X-API-Key:api_key,Content-Type:application/json}body{q:query,hl:en,gl:us,page:1}rrequests.post(self.base_url,headersheaders,jsonbody,timeout30)datar.json()foritemindata.get(organic,[]):urlitem.get(link,)# 检查是否已记录existingself.db.execute(SELECT 1 FROM competitor_content WHERE url ?,(url,)).fetchone()ifnotexisting:new_pages.append({url:url,title:item.get(title,),first_seen:datetime.now().isoformat(),content_type:self._detect_content_type(item.get(title,))})# 存入新内容forpageinnew_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()returnnew_pagesdef_detect_content_type(self,title:str)-str:title_lowertitle.lower()ifany(wintitle_lowerforwin[how to,guide,tutorial]):returnguideelifany(wintitle_lowerforwin[best,top,vs]):returnlisticleelifreviewintitle_lower:returnreviewreturnarticle三、告警系统defcheck_alerts(self,competitor:str)-List[Dict]:检查竞品异常变化alerts[]# 1. 排名突增告警recentpd.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_,rowinrecent.iterrows():ifrow[prev_rank]androw[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_contentpd.read_sql(f SELECT * FROM competitor_content WHERE competitor {competitor} AND first_seen date(now, -3 days) ,self.db)iflen(new_content)3:alerts.append({type:content_surge,competitor:competitor,new_pages:len(new_content),severity:medium})returnalerts四、竞品对比报告defgenerate_competitor_report(self,competitor:str,days:int30)-Dict:生成竞品分析报告# 排名变化rankingspd.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_contentpd.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:typesnew_content[content_type].value_counts()dominanttypes.index[0]iflen(types)0elseunknownstrategies{guide:Focus on educational content,listicle:Focus on comparison content,review:Focus on product reviews}returnstrategies.get(dominant,Mixed strategy)五、总结竞品监控的核心自动化每天自动采集不需要人工多维度排名、内容、Schema、外链告警异常变化立即通知报告定期生成分析报告行动基于数据制定反击策略竞品监控不是偷窥是学习。对手在做什么、什么有效这些数据帮你少走弯路。用SerpBase做竞品监控的成本很低——监控5个竞品×50个关键词×30天7,500次查询成本$2.25。比买Semrush便宜100倍。