克服Facebook Marketing API中的速率限制

时间:2018-02-01 23:09:19

标签: python facebook facebook-graph-api facebook-marketing-api

特别是,我试图做一些与此问题非常相似的事情(同样的问题):FB Ads API (#17) User request limit reached

但是,我试图在python中这样做(并且自从' 15以来API已经发生了很大变化)。这是我的代码(即使有睡眠时间,也会把我踢出去) - 我想知道是否有人可以帮我调用类似信息的数组,以减少我的总呼叫次数。

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])

更多一般,我意味着如何在此限制范围内为我的需求(大规模更改)进行编码?实际上,我想编写一个代码来完成并更改我公司的每个广告集中的一些选项(例如"展开兴趣时......"从off到on)。我们有数百个广告集,并且API文档说,更改消耗的次数比创作多10到100倍(我不会卡在两者上,只是读取!)。这只是一个例如,在每次更改之间睡眠代码60秒的问题吗?他们不清楚你在一段时间内收到多少电话,或者检查这些电话的时间有多宽。例如,如果它是每日限制,那么睡眠不会帮助我更改1200个广告集'选项。

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

3 个答案:

答案 0 :(得分:1)

如果您现在只是阅读数据,为什么不进行批量请求?我做的和你一样,但最后却要求更多的数据(我不得不摆弄它,因为有太多的数据,FB也不允许这样做)然后循环数据。

就我的目的而言,如果达到极限,我会批量处理异步请求+睡眠(10秒)。适合我。

答案 1 :(得分:0)

将此添加到您的代码中,您将不必担心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.1/act_'+account_number+'/insights?access_token='+my_access_token)
    usage=float(find_between(check.headers['x-ad-account-usage'],':','}'))
    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)

答案 2 :(得分:0)

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

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() 因为有些值被当作文本处理,所以为了将其转换为可下标的对象。