怎么按关键词搜 Meta 广告库,并跟踪某个广告主的广告
按顺序用三个接口:Meta 广告库搜索按关键词找广告,Meta 广告主的广告列出某个 Facebook 主页在投的广告,Meta 广告详情过段时间复查单条广告。下面的示例一共 7 次调用,花费 $0.028;失败的调用不扣费。
更新于
要做的事:你准备进入一个品类,想看看已经在里面的品牌是怎么在 Facebook 和 Instagram 上投广告的。用什么钩子、什么优惠、什么落地页,一条广告能跑多久。先按关键词搜广告库,看谁在投;再打开投得最多的那个广告主的完整列表;挑几条广告存下来,过段时间再看。最后得到三张表:关键词下的广告、某个广告主的广告,以及一周后入选广告的状态。
不需要 Meta 开发者应用,不用 access token,也不用登录 Facebook。每次调用就是带着 key 发一个 HTTPS 请求。
分步操作
第一步:按关键词搜广告
调用Meta 广告库搜索,query 填关键词。四个筛选参数:
country:ISO 国家代码,比如US、DE;不填为全部国家。status:active(默认,正在投放)、inactive(已停投)或all(全部)。media:all(默认)、image(只看图片)或video(只看视频)。sort:impressions(默认,按曝光从高到低)或newest(按最新)。
一次调用最多返回 30 条广告,每次 $0.004。每条广告有 id(广告库 ID)、url、advertiser(Facebook 主页的 id、name 和 url)、title、文案 text、format(image、video、carousel、text 或 dynamic)、images、videos、landing_url、cta、platforms(比如 facebook、instagram)、active 和 first_shown_at。
curl -G "https://api.okdata.online/v1/meta/ads/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=electrolyte powder' \
-d country=US -d status=active -d media=video -d sort=impressions
要第二页,就把 page.next_cursor 原样作为 cursor 传回去。然后按 advertiser.id 数一数,就知道谁在这个关键词上投得最多。
第二步:列出某个广告主的广告
把第一步拿到的主页 ID 作为 id 传给Meta 广告主的广告,或者把品牌在 Facebook 主页上的名称作为 name 传入。两个只能给一个:都给或都不给会返回 invalid_params,不扣费。country、status、media、sort 这几个筛选同样可用,每页最多 30 条,每次 $0.004。
curl -G "https://api.okdata.online/v1/meta/advertisers/ads/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
-d id=107364829105372 -d country=US -d status=active -d sort=newest
sort=newest 会把品牌最近上的广告排在前面,每周例行查看时正好用它。用 ID 比用名称稳妥:好几个主页可能同名,ID 只对应一个。
第三步:复查单条广告
Meta 广告详情接收广告库 id 或广告链接 url,返回一条广告,每次 $0.004,带 active、first_shown_at 和 last_shown_at。把你挑中的广告 ID 存下来,一周后调三次详情,就知道哪些还在投、各自跑了多久。能连着跑几个月的广告,通常就是效果好的。
curl -G "https://api.okdata.online/v1/meta/ads/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
-d id=1290374658821904 \
-d fields=id,active,first_shown_at,last_shown_at,landing_url
第四步:用 Python 写
import collections
import os
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
def pages(path, n, **params):
cursor = None
for _ in range(n):
body = requests.get(API + path, headers=HEADERS, params={**params, **({"cursor": cursor} if cursor else {})}, timeout=60).json()
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
yield from body["data"]["items"]
if not body["page"]["has_more"]:
return
cursor = body["page"]["next_cursor"]
ads = list(pages("/v1/meta/ads/search", 2, query="electrolyte powder", country="US", status="active", media="video"))
top_page = collections.Counter(a["advertiser"]["id"] for a in ads if a["advertiser"]["id"]).most_common(1)[0][0]
for a in pages("/v1/meta/advertisers/ads/list", 2, id=top_page, country="US", status="active", sort="newest"):
print(a["first_shown_at"], a["format"], a["landing_url"], (a["text"] or "")[:80])
注意事项
- Meta 官方 API 能返回什么。 Meta 的 Ads Archive 接口文档写明:没有触达欧盟任何地区的广告,只有涉及社会议题、选举或政治时才会返回。做政治广告研究,或者需要 Meta 官方细分数据的欧盟广告,用官方 API 最合适。这里的接口读的是公开的广告库页面,美国、亚洲的普通商业广告也能拿到。
- 花费和触达。 广告库不公布欧盟以外商业广告的花费和触达,所以这类广告的
reach为 null。在欧盟投放过的广告会带上 Meta 给出的欧盟触达人数。 - 已停投的广告。
status=inactive只能返回公开广告库里还看得到的停投广告,欧盟以外的商业广告往往不多。想要某个品牌的投放历史,就每周自己存一份。 - 动态广告。 按观众动态拼装的商品目录广告,
format为dynamic,常常没有文案,因为广告库显示的是模板而不是正文。 - 额外字段。
view=full会加上ext.variants(广告库归在一起的版本数)、ext.page_likes、ext.categories,欧盟广告还有ext.eu_payer和ext.eu_beneficiary。 - 想留的素材及时下载。 图片和视频链接指向 Meta 的服务器,可能会失效。
- 重试不会重复扣费。 每次调用带一个
Idempotency-Key请求头;24 小时内同样的请求配同样的 key,会拿回存好的结果,不再扣费。
官方 API 要多少钱、有什么门槛,见Meta 广告库 API 要钱吗。要同时盯一个竞品在 Meta、Google 和 TikTok 上的广告,看怎么查竞品在三个广告库里的广告。
示例花费
搜两页美国在投的电解质冲剂(electrolyte powder)视频广告,取某个广告主两页在投广告,一周后再复查入选的 3 条
| 接口 | 调用次数 | 单价 | 小计 |
|---|---|---|---|
| Meta 广告库搜索 | 2 | $0.004 | $0.008 |
| Meta 广告主的广告 | 2 | $0.004 | $0.008 |
| Meta 广告详情 | 3 | $0.004 | $0.012 |
| 合计 | 7 | $0.028 |
按本页生成时的价格计算。失败的调用不扣费。
在你的 AI 里用(MCP)
先接好 MCP 服务,然后直接说你要什么。智能体会自己找到这些接口、看清价格,再用你的余额调用。
可以这样说在 Meta 广告库搜美国正在投放的 electrolyte powder 视频广告,按曝光从高到低,取两页。告诉我哪些广告主出现得最多,再列出排第一的那个广告主两页在投广告,带文案、落地页和开始投放日期。
智能体第一次调用 call 工具时发送的内容
{
"endpoint": "meta.ads.search",
"params": {
"query": "portable espresso"
},
"idempotency_key": "<新的 UUID>"
}