0

我最近开始使用 Facebook 营销 API,使用facebook_businessPython 的 SDK(在 Ubuntu 20.04 上运行 v3.9)。我想我已经大致了解了它是如何工作的,但是,对于如何处理 API 受速率限制的任意方式,我仍然有点茫然。

具体来说,我试图做的是从我的广告帐户上运行过的所有广告系列中检索所有广告集,无论它们effective_statusACTIVE、还是。PAUSEDDELETEDARCHIVED

因此,我为我的广告帐户提取了所有广告系列。这些存储在一个字典中,其中键表示effective_status,就像这样,称为output

{'ACTIVE': ['******************',
  '******************',
  '******************'],
 'PAUSED': ['******************',
  '******************',
  '******************'}

然后,我尝试提取广告集 ID,如下所示:

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

现在,每当我运行它时,它都会在不同的时间崩溃,并出现以下错误:

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": "***************"
      }
    }

我无法重现它崩溃的时间,但是,它肯定不需要约 600 次调用(见这里:https ://stackoverflow.com/a/29690316/5080858 ),正如你所见,我m 在每个 API 调用之前就睡着了。您可能会建议我应该只调用get_ad_setsAdAccount 端点上的方法,但是,与上面的代码相比,这会拉取更少的广告集,即使在它崩溃之前也是如此。对于我的用例,重要的是要提取已结束的广告以及正在进行的广告,因此获取尽可能多的数据很重要。

我对此有点恼火——看到我们为这些广告的运行付费,你会认为 FB 会尽可能容易地通过 API 检索关于它们的信息,而不是引入类似于那些的 API 速率限制对于不一定拥有的有价值的数据。

无论如何,我将不胜感激任何形式的建议或见解 - 也许还有一种我没有考虑过的更好的方法。

提前谢谢了!

4

1 回答 1

0

错误'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参数 in params)并使用批处理调用:我可以向您保证,这将对您有很大帮助,并且会减少程序运行时间.

我希望我是有帮助的。

于 2021-07-22T21:31:58.453 回答