克服 Facebook 营销中的速率限制 API

Overcoming Rate Limiting in Facebook Marketing API

具体来说,我正在尝试做一些与这个问题非常相似的事情(有同样的问题):FB Ads API (#17) User request limit reached

但是,我正在尝试在 python 中执行此操作(并且 API 自 15 年以来已经发生了很大变化)。这是我的代码(即使有睡眠时间,它也会把我踢出去)- 我想知道是否有人可以帮助我调用具有类似信息的数组,以减少我的总调用次数。

my_account = AdAccount(ad_account_id)
camps = my_account.get_campaigns(fields=[Campaign.Field.name])

for campaign in camps[0:100]:
    time.sleep(5)
    print campaign[Campaign.Field.name]
    adsets = campaign.get_ad_sets([AdSet.Field.name, AdSet.Field.status])
    for adset in adsets:
        print '\t', adset[AdSet.Field.name]
        for stat in adset.get_insights(fields=[
        'impressions',
        'clicks',
        'spend',
        'unique_clicks',
        ]):
            for statfield in stat:
                print "\t\t%s:\t%s" % (statfield, stat[statfield])

更多一般,我如何意味着在这个限制内为我的需要(大规模改变)编码?实际上,我想编写一段代码来遍历并更改我公司每个广告集中的几个选项(例如 "Expand Interests when..." 从关闭到打开)。我们有数百个广告集,API 文档说更改所消耗的调用次数是创建次数的 10-100 倍(我都没有坚持,只是阅读!)。这仅仅是一个问题,比方说,在每次更改之间让代码休眠 60 秒吗?他们不太清楚您在一个时间段内接到了多少个电话,或者检查这些电话的时间段有多长。例如,如果是每日限制,那么睡觉不会帮助我更改 1200 个广告集的选项。

我确实看到了有关升级的文档 (https://developers.facebook.com/docs/marketing-api/access),但是在审查过程中,一切都基于 public(面向客户,多用户)应用程序。我想要做的就是能够从仅限桌面开发人员的内部脚本进行调用以进行批量更改。我是不是找错地方了?

如果您现在只是读取数据,为什么不进行批量请求?我和你做的一样,但最终请求了更多数据(我不得不 fiddle ,因为数据太多,FB 也不允许这样做),然后循环遍历数据。

出于我的目的,如果达到我的极限,我会执行批量异步请求 + 休眠(10 秒)。对我来说效果很好。

将此添加到您的代码中,您将永远不必担心 FB 的速率限制。 一旦接近极限,您的脚本就会自动休眠,然后在冷却后从它离开的地方恢复。享受:)

import logging
import requests as rq

#Function to find the string between two strings or characters
def find_between( s, first, last ):
    try:
        start = s.index( first ) + len( first )
        end = s.index( last, start )
        return s[start:end]
    except ValueError:
        return ""

#Function to check how close you are to the FB Rate Limit
def check_limit():
    check=rq.get('https://graph.facebook.com/v3.3/act_'+account_number+'/insights?access_token='+my_access_token)
    call=float(find_between(check.headers['x-business-use-case-usage'],'call_count":','}'))
    cpu=float(find_between(check.headers['x-business-use-case-usage'],'total_cputime":','}'))
    total=float(find_between(check.headers['x-business-use-case-usage'],'total_time":',','))
    usage=max(call,cpu,total)
    return usage

#Check if you reached 75% of the limit, if yes then back-off for 5 minutes (put this chunk in your loop, every 200-500 iterations)
if (check_limit()>75):
    print('75% Rate Limit Reached. Cooling Time 5 Minutes.')
    logging.debug('75% Rate Limit Reached. Cooling Time 5 Minutes.')
    time.sleep(300)

它可能对谁有用,我通过捕获每次 API 调用后返回的“headers”解决了这个问题。

my_account = AdAccount(ad_account_id)
camps = my_account.get_campaigns(fields=[Campaign.Field.name])
for campaign in camps[0:100]:
    time.sleep(5)
    print campaign[Campaign.Field.name]
    adsets = campaign.get_ad_sets([AdSet.Field.name, AdSet.Field.status])
    for adset in adsets:
        print '\t', adset[AdSet.Field.name]
        adset_insights = adset.get_insights(fields=[
        'impressions',
        'clicks',
        'spend',
        'unique_clicks',
        ])
        for stat in adset_insights:
            for statfield in stat:
                print "\t\t%s:\t%s" % (statfield, stat[statfield])
        rate_limit = json.loads(adset_insights.headers()[
        'x-fb-ads-insights-throttle'])
        if rate_limit['acc_id_util_pct'] > your_percentage_limit:
            time.sleep(150)

json.loads()因为有些值被当作文本,所以为了将其转换为可下标的object.

除了,还有其他参数如:

  • call_count(调用百分比)
  • total_time(占总时间的百分比)
  • total_cputime(占总 CPU 时间的百分比)

total_time 和 total_cputime 限制为 100。

acc_id_util_pct 的最大值是 100,因为它也是一个百分比,但即使您达到了该限制,您也可以发出更多请求,因为您没有达到 total_time 和 total_cputime 限制还没。

并且 max call_count 的计算对于每种类型的请求都是不同的。您可以从 link

了解更多相关信息