如何解决Facebook Marketing API - 如何处理通过广告系列 ID 检索*所有*广告集的速率限制?
我最近开始使用 Facebook Marketing API,使用适用于 Python 的 facebook_business
SDK(在 Ubuntu 20.04 上运行 v3.9)。我想我大部分时间都在思考它是如何工作的,但是,对于如何处理 API 速率限制的任意方式,我仍然有点茫然。
具体来说,我试图做的是从曾经在我的广告帐户上运行的所有广告系列中检索所有广告集,无论它们的 effective_status
是否为 {{ 1}}、ACTIVE
、PAUSED
或 DELETED
。
因此,我为我的广告帐户提取了所有广告系列。它们存储在字典中,其中键表示 ARCHIVED
,就像这样,称为 effective_status
:
output
然后,我正在尝试提取广告集 ID,如下所示:
{'ACTIVE': ['******************','******************','******************'],'PAUSED': ['******************','******************'}
现在,每当我运行它时,它都会在不同的时间崩溃,并出现以下错误:
import pandas as pd
import json
import re
import time
from random import *
from facebook_business.api import FacebookAdsApi
from facebook_business.adobjects.adaccount import AdAccount # account-level info
from facebook_business.adobjects.campaign import Campaign # campaign-level info
from facebook_business.adobjects.adset import AdSet # ad-set level info
from facebook_business.adobjects.ad import Ad # ad-level info
# auth init
app_id = open(APP_ID_PATH,'r').read().splitlines()[0]
app_secret = open(APP_SECRET_PATH,'r').read().splitlines()[0]
token = open(APP_ACCESS_TOKEN,'r').read().splitlines()[0]
# init the connection
FacebookAdsApi.init(app_id,app_secret,token)
campaign_types = list(output.keys())
ad_sets = {}
for status in campaign_types:
ad_sets_for_status = []
for campaign_id in output[status]:
# sleep and wait for a random time
sleepy_time = uniform(1,3)
time.sleep(sleepy_time)
# pull the ad_sets for this particular campaign
campaign_ad_sets = Campaign(campaign_id).get_ad_sets()
for entry in campaign_ad_sets:
ad_sets_for_status.append(entry['id'])
ad_sets[status] = ad_sets_for_status
我无法重现它崩溃的时间,但是,它肯定不需要大约 600 次调用(请参阅此处:https://stackoverflow.com/a/29690316/5080858),而且正如您所看到的,我在每个API 调用。您可能会建议我只在 AdAccount 端点上调用 FacebookRequestError:
Message: Call was not successful
Method: GET
Path: https://graph.facebook.com/v11.0/23846914220310083/adsets
Params: {'summary': 'true'}
Status: 400
Response:
{
"error": {
"message": "(#17) User request limit reached","type": "OAuthException","is_transient": true,"code": 17,"error_subcode": 2446079,"fbtrace_id": "***************"
}
}
方法,但是,即使在崩溃之前,这也比上述代码提取的广告集少。就我的用例而言,重要的是拉取已结束的广告和正在进行的广告,因此获取尽可能多的数据很重要。
我对此有点恼火——看到我们为这些广告的运行付费,你会认为 FB 会尽可能轻松地通过 API 检索它们的信息,而不是引入 API 速率限制类似于那些不一定拥有的有价值数据。
无论如何,我很感激任何形式的建议或见解 - 也许还有一种我没有考虑过的更好的方法来做到这一点。
非常感谢!
解决方法
'code': 17
的错误意味着您达到了调用限制,为了获得更多节点,您必须等待。
首先我会以这种方式处理错误:
from facebook_business.exceptions import FacebookRequestError
...
for status in campaign_types:
ad_sets_for_status = []
for campaign_id in output[status]:
# keep trying until the request is ok
while True:
try:
campaign_ad_sets = Campaign(campaign_id).get_ad_sets()
break
except FacebookRequestError as error:
if error.api_error_code() in [17,80000]:
time.sleep(sleepy_time) # sleep for a period of time
for entry in campaign_ad_sets:
ad_sets_for_status.append(entry['id'])
ad_sets[status] = ad_sets_for_status
此外,我还建议您从帐户中获取节点列表(通过使用 'level': node
中的 params
参数)并使用批处理调用:我可以向您保证会帮助你很多,它会减少程序运行时间。
希望对您有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。