用搜索引擎 API 搭一个 SEO 关键词监控工具:定时追踪排名、广告和相关搜索
一、为什么要做关键词监控,而不是手动搜一遍?
做 SEO、广告投放、竞品分析和品牌舆情时,很多团队都会定期查看搜索结果。 比如一个跨境电商品牌,可能每天都要看这些问题: - 自己的网站在目标关键词下排第几? - 竞品官网有没有超过自己? - 搜索结果里有没有新的测评文章或比价页面? - 品牌词下面有没有负面内容? - 竞品有没有投放广告结果? - Google / Bing 上的搜索结果有没有发生变化? 如果只是偶尔查一次,人工打开搜索引擎就可以。但如果要持续监控几十个关键词,比如:
wireless earbuds portable monitor brand name review brand name coupon competitor name
人工搜索就很容易出问题。
首先,手动搜索无法保证稳定性。不同地区、不同语言、不同设备、不同浏览器状态下,搜索结果可能不一样。其次,人工记录排名很低效,也不方便做历史趋势对比。今天排第 3,明天排第 5,如果没有结构化记录,很难判断排名变化是偶然波动,还是竞争环境发生了变化。
所以这次我不再只是单次请求搜索结果,而是尝试用搜索引擎 API 搭一个简单的 SEO 关键词监控工具。
目标很明确:
-
配置一组关键词;
-
每隔 1 小时调用一次搜索引擎 API;
-
获取自然搜索结果、相关搜索和广告结果;
-
解析目标域名排名;
-
保存历史数据;
-
输出排名变化趋势图。
整体流程如下:
Plain
关键词列表
↓
搜索引擎 API 请求
↓
解析自然结果 / 广告结果 / 相关搜索
↓
保存每小时数据
↓
生成排名趋势图
↓
用于 SEO、广告、舆情和竞品分析
这类监控工具本身并不复杂,但它解决的核心问题,是把原本零散、依赖人工判断的搜索行为,转化为可重复执行、可持续积累的数据监控流程。只有不断记录同一关键词在相同地区、语言和设备条件下的搜索结果,后续的排名趋势、广告竞争和内容变化分析才有可靠的数据基础。
因此,在正式编写监控脚本之前,首先需要解决两个问题:一是如何把人工输入关键词、选择搜索引擎和设置地区等操作转换为标准化请求;二是如何保证每次请求使用相同的参数条件,减少搜索环境变化对结果的影响。搜索引擎 API 正好提供了这样的能力,它可以把关键词、地区、语言、设备和输出格式统一封装为请求参数,使后续的定时调用和批量监控成为可能。
二、准备 API 请求:认证、关键词和参数构造
搭建关键词监控工具的第一步,是先完成搜索引擎 API 的请求配置。与手动打开搜索页面相比,API 请求不仅可以批量提交关键词,还可以明确指定搜索引擎、地区、语言、设备类型和返回格式,从而让不同时间获得的数据具有更强的可比性。
在此基础上,后续脚本只需要按照设定的时间间隔重复发送请求,再对返回结果进行解析和保存,就能够逐步形成连续的关键词排名历史数据。
立即体验:dataify.com?utm_source=undoom&utm_term=01

这次我使用的请求地址是:
Plain
https://scraperapi.dataify.com/request
请求时需要在 Header 中带上 API Token:
Plain
Authorization: Bearer YOUR_TOKEN

这里的 YOUR_TOKEN 要替换成自己的 Token。真实 Token 属于敏感信息,不要放到公开截图、文章或者代码仓库里。
一个基础请求可以写成:
Bash
curl -X POST 'https://scraperapi.dataify.com/request' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'engine=google' \
-d 'q=wireless earbuds' \
-d 'json=1' \
-d 'google_domain=google.com' \
-d 'gl=us' \
-d 'hl=en' \
-d 'device=desktop'
如果要监控 Bing,也可以把 engine 换成对应的搜索引擎类型。实际使用时,可以根据业务目标配置多个搜索引擎。

这里我可以先定义一组关键词:
Python
keywords = [
"wireless earbuds",
]
运行结果如下:

这样后面就可以判断:每个关键词下,目标网站有没有出现在搜索结果前 10 名,具体排名第几。
三、解析搜索结果:判断 apple.com 排名
搜索引擎 API 返回 JSON 后,重点不是直接看完整结果,而是提取几个核心字段。
这次主要关注三类数据:
Plain
自然搜索结果:判断 apple.com 排名
广告结果:观察关键词下的广告竞争情况
相关搜索:发现新的关键词机会
先定义目标域名和关键词列表:
Plain
TARGET_DOMAIN = "apple.com"
KEYWORDS = [
"iphone 16",
"macbook air",
"apple watch",
"airpods pro",
"apple store"
]
接下来写一个函数,从自然搜索结果中查找 apple.com 出现的位置:
Plain
def extract_organic_rank(result, target_domain):
organic_results = result.get("organic_results", [])
for index, item in enumerate(organic_results, start=1):
link = item.get("link", "")
if target_domain in link:
return {
"rank": index,
"title": item.get("title"),
"link": link,
"snippet": item.get("snippet")
}
return {
"rank": None,
"title": None,
"link": None,
"snippet": None
}
这段代码的逻辑很简单:
-
读取
organic_results; -
从第 1 条结果开始遍历;
-
判断链接里是否包含
apple.com; -
如果包含,就记录当前排名;
-
如果没有出现,就返回空值。
比如搜索 iphone 16 时,如果 apple.com 出现在第 1 条,就会返回:
Plain
{
"rank": 1,
"title": "iPhone 16 - Apple",
"link": "https://www.apple.com/iphone-16/",
"snippet": "Explore iPhone 16 features, design, camera and more..."
}
如果搜索某个关键词时,前几条结果中没有 apple.com,就记录为 None。后续画图时,可以把 None 单独处理,比如表示"未进入监控范围"。
除了自然搜索排名,还可以统计广告结果数量:
Plain
def extract_ads_count(result):
ads = result.get("ads", [])
return len(ads)
广告结果数量可以反映某个关键词的广告竞争程度。比如 iphone 16 这种高商业价值关键词,广告结果数量可能会更高。
再提取相关搜索:
Plain
def extract_related_searches(result):
related = result.get("related_searches", [])
queries = []
for item in related:
query = item.get("query")
if query:
queries.append(query)
return " | ".join(queries)
相关搜索可以帮助扩展关键词池。比如搜索 iphone 16 后,相关搜索中可能出现:
Plain
iphone 16 pro
iphone 16 price
iphone 16 pro max
iphone 16 colors
iphone 16 release date
这些词可以继续加入后续监控列表。
四、Python 实现:每小时监控一次关键词排名
下面把 API 请求、结果解析和 CSV 保存组合成一个完整脚本。
这个脚本会完成以下任务:
-
依次请求关键词列表;
-
调用搜索引擎 API;
-
判断 apple.com 在谷歌上面,自然搜索结果中的排名;
-
统计广告结果数量;
-
提取相关搜索;
-
保存到 CSV;
-
每隔 1 小时自动运行一次。
其中,gl 和 hl 是两个会直接影响搜索结果的重要参数:
-
gl="us"表示将搜索结果的目标地区设置为美国; -
hl="en"表示将搜索结果的界面语言设置为英文。
这两个参数并不是简单的显示设置。搜索引擎可能会根据地区和语言返回不同的自然搜索结果、广告内容及相关搜索词。例如,同一个关键词在美国地区和其他地区搜索时,出现的网站、页面排序和广告数量都可能不同。
因此,在进行长期关键词监控时,应尽量固定 gl 和 hl 的取值,保证不同时间采集的数据处于相对一致的搜索环境中。否则,排名变化可能并不是网站实际排名发生了波动,而是地区或语言条件不同造成的结果差异。
本次监控面向美国英文搜索环境,因此设置为:
Plain
"gl": "us",
"hl": "en",
如果后续需要监控其他市场,也可以根据目标地区和语言进行调整。例如,监控英国英文搜索环境时,可以将 gl 修改为 uk,同时继续使用 hl="en"。
Python
import requests
import csv
import time
from datetime import datetime
API_URL = "https://scraperapi.dataify.com/request"
API_TOKEN = "YOUR_TOKEN"
TARGET_DOMAIN = "apple.com"
KEYWORDS = [
"iphone 16",
"macbook air",
"apple watch",
"airpods pro",
"apple store"
]
HEADERS = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/x-www-form-urlencoded",
}
def call_search_api(keyword):
data = {
"engine": "google",
"q": keyword,
"json": "1",
"google_domain": "google.com",
"gl": "us",
"hl": "en",
"device": "desktop",
}
response = requests.post(API_URL, headers=HEADERS, data=data, timeout=60)
response.raise_for_status()
return response.json()
def extract_organic_rank(result, target_domain):
organic_results = result.get("organic_results", [])
for index, item in enumerate(organic_results, start=1):
link = item.get("link", "")
if target_domain in link:
return {
"rank": index,
"title": item.get("title"),
"link": link,
"snippet": item.get("snippet")
}
return {
"rank": None,
"title": None,
"link": None,
"snippet": None
}
def extract_ads_count(result):
ads = result.get("ads", [])
return len(ads)
def extract_related_searches(result):
related = result.get("related_searches", [])
queries = []
for item in related:
query = item.get("query")
if query:
queries.append(query)
return " | ".join(queries)
def save_rows(rows, file_path="apple_seo_keyword_monitor.csv"):
fieldnames = [
"created_at",
"keyword",
"target_domain",
"rank",
"title",
"link",
"snippet",
"ads_count",
"related_searches"
]
try:
with open(file_path, "r", encoding="utf-8-sig") as f:
file_exists = True
except FileNotFoundError:
file_exists = False
with open(file_path, "a", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
if not file_exists:
writer.writeheader()
writer.writerows(rows)
def run_once():
rows = []
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for keyword in KEYWORDS:
print(f"正在监控关键词:{keyword}")
try:
result = call_search_api(keyword)
rank_info = extract_organic_rank(result, TARGET_DOMAIN)
ads_count = extract_ads_count(result)
related_searches = extract_related_searches(result)
rows.append({
"created_at": now,
"keyword": keyword,
"target_domain": TARGET_DOMAIN,
"rank": rank_info["rank"],
"title": rank_info["title"],
"link": rank_info["link"],
"snippet": rank_info["snippet"],
"ads_count": ads_count,
"related_searches": related_searches
})
except Exception as e:
rows.append({
"created_at": now,
"keyword": keyword,
"target_domain": TARGET_DOMAIN,
"rank": None,
"title": None,
"link": None,
"snippet": f"ERROR: {e}",
"ads_count": None,
"related_searches": None
})
save_rows(rows)
print("本轮监控完成")
if __name__ == "__main__":
while True:
run_once()
print("等待 1 小时后继续下一轮监控")
time.sleep(3600)
运行后结果如下,程序会生成一个 CSV 文件:

里面会持续记录每个关键词的搜索结果表现。数据如下:

这张表的价值在于,它不是一次性的搜索截图,而是一份可以持续增长的历史数据。
通过它可以观察:
-
apple.com 在不同关键词下是否稳定排名靠前;
-
某个关键词是否突然下降;
-
广告结果数量是否增加;
-
相关搜索中是否出现新的热门词;
-
不同产品词之间的搜索竞争强度是否不同。
五、生成趋势图:观察排名变化
有了 CSV 数据后,就可以进一步画趋势图。
这里以 iphone 16 为例,查看 apple.com 在这个关键词下的排名变化。
Python
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("apple_seo_keyword_monitor.csv")
keyword = "iphone 16"
target_df = df[df["keyword"] == keyword].copy()
target_df["created_at"] = pd.to_datetime(target_df["created_at"])
target_df["rank"] = pd.to_numeric(target_df["rank"], errors="coerce")
plt.figure(figsize=(10, 5))
plt.plot(target_df["created_at"], target_df["rank"], marker="o")
plt.gca().invert_yaxis()
plt.title(f"SEO Ranking Trend: {keyword}")
plt.xlabel("Time")
plt.ylabel("Rank")
plt.grid(True)
plt.tight_layout()
plt.savefig("iphone_16_ranking_trend.png", dpi=200)
plt.show()
运行结果如下:

这里有一个小细节:SEO 排名越小越好。第 1 名比第 5 名更好,这样排名越靠前,图上位置越高,看起来更符合直觉。
在 iphone 16 这个关键词下,10:00 和 11:00 都保持在第 1 位,说明这两个时间点官网在搜索结果中占据最靠前位置。到了 12:00,排名从第 1 位下降到第 2 位。这个变化虽然不大,但已经说明搜索结果存在波动。如果只是人工偶尔搜索一次,很容易忽略这种变化;但通过定时调用搜索引擎 API,就可以把这种排名变化记录下来,并形成可视化趋势。
如果还想观察广告竞争强度,可以画广告数量变化:
Python
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("apple_seo_keyword_monitor.csv")
keyword = "iphone 16"
target_df = df[df["keyword"] == keyword].copy()
target_df["created_at"] = pd.to_datetime(target_df["created_at"])
target_df["ads_count"] = pd.to_numeric(target_df["ads_count"], errors="coerce")
plt.figure(figsize=(10, 5))
plt.plot(target_df["created_at"], target_df["ads_count"], marker="o")
plt.title(f"Ads Count Trend: {keyword}")
plt.xlabel("Time")
plt.ylabel("Ads Count")
plt.grid(True)
plt.tight_layout()
plt.savefig("iphone_16_ads_count_trend.png", dpi=200)
plt.show()
这样就可以同时观察两个指标:
Plain
自然排名变化:apple.com 排第几
广告数量变化:这个关键词竞争是否变强
如果某个时间点排名下降,同时广告数量上升,就可能说明该关键词下的搜索竞争正在变激烈。

六、这个监控工具可以用在哪些场景?
虽然这次使用的是 Apple 产品关键词,但这套方法并不局限于监控 apple.com。实际应用中,可以保持关键词列表不变,同时记录搜索结果中出现的不同网站、页面类型和对应排名,从而分析同一关键词下的竞争格局。
例如,继续监控以下关键词:
-
iphone 16
-
macbook air
-
apple watch
-
airpods pro
-
apple store
在每次获取搜索结果后,除了记录 apple.com 的排名,还可以进一步提取 Amazon、Walmart、Best Buy 等电商平台,以及科技媒体、测评网站、论坛和视频网站的域名与排名。
SEO:监控目标网站与竞品网站排名
SEO 团队可以围绕一组固定关键词,持续记录目标网站和竞品网站在自然搜索结果中的位置。
例如,在监控 iphone 16 时,可以同时记录:
-
apple.com:第 1 名
-
amazon.com:第 3 名
-
bestbuy.com:第 5 名
-
techradar.com:第 7 名
这样不仅能判断目标网站自身排名是否发生变化,还可以观察排名下降是否由竞品官网、电商平台、新闻页面或测评内容上升造成。
相比只记录 apple.com 是否进入前 10 名,同时保存主要竞争域名及其排名,更有利于分析搜索结果整体结构的变化。
电商:观察固定产品词下的平台竞争格局
电商分析不一定需要重新配置一组关键词,也可以继续使用原有的 Apple 产品词,重点观察搜索结果中出现了哪些电商平台。
例如,在 airpods pro 的搜索结果中,可以记录:
-
apple.com 的排名;
-
amazon.com 的排名;
-
walmart.com 的排名;
-
bestbuy.com 的排名;
-
其他电商或比价网站的排名。
通过持续记录,可以判断同一个产品词下,哪些平台长期占据靠前位置,哪些平台的排名正在上升,以及品牌官网与第三方销售平台之间的搜索流量竞争关系。
这类数据可以用于渠道分析、竞品监测和商品页面优化。
广告:观察相同关键词下的广告竞争变化
广告监控也可以继续使用相同关键词,不需要单独改成带有 deal、discount 或 sale 的搜索词。
在每次请求中,可以记录:
-
广告结果数量;
-
广告主域名;
-
广告出现位置;
-
广告标题与落地页;
-
自然搜索结果是否受到广告区域挤压。
例如,在 iphone 16 关键词下,如果广告数量从 1 条增加到 4 条,同时 apple.com 的自然排名虽然没有变化,但页面中的实际展示位置有所下移,就说明该关键词的广告竞争正在增强。
因此,广告数量和广告主变化可以与自然排名数据结合分析,而不是单独更换关键词进行监控。
内容与社媒:识别搜索结果中的内容来源变化
对于内容和社媒分析,同样可以保留原来的关键词,观察搜索结果中是否开始出现新的内容平台。
例如,在 apple watch 的搜索结果中,可以记录是否出现:
-
YouTube 视频;
-
Reddit 讨论;
-
TikTok 页面;
-
科技媒体测评;
-
新闻报道;
-
问答或论坛页面。
如果某段时间内,视频、论坛讨论或测评文章的排名持续上升,就说明该关键词下的搜索结果结构正在发生变化,用户可能不再只关注品牌官网和商品页面,而是更关注使用体验、测评内容和社区讨论。通过这种方式,可以在不改变关键词的情况下,同时完成品牌排名监控、电商平台分析、广告竞争观察和内容来源变化分析。
七、总结
这篇文章的重点不是单次获取搜索结果,而是把搜索引擎 API 做成一个可以持续运行的 SEO 关键词监控工具。
完整流程是:
Plain
配置目标域名 apple.com
↓
配置关键词列表
↓
调用搜索引擎 API
↓
解析自然搜索结果、广告结果和相关搜索
↓
记录 apple.com 当前排名
↓
每小时保存一次 CSV
↓
生成排名趋势图
相比手动搜索,这种方式更适合长期监控。它可以持续记录关键词排名变化,也可以观察广告竞争强度、相关搜索变化和搜索结果中的新竞争者。
对于 SEO、电商、广告、社媒和舆情团队来说,搜索结果不是一个静态页面,而是一组可以持续追踪的数据。通过搜索引擎 API 把这些数据保存下来,后续就可以做趋势分析、异常告警、竞品监测和内容优化。