【问题标题】:Batch create campaigns via Facebook ads API with Python?使用 Python 通过 Facebook 广告 API 批量创建活动?
【发布时间】:2021-08-17 15:27:16
【问题描述】:

我正在尝试构建一个 API 工具来一次创建 100 多个广告系列,但到目前为止,我一直遇到超时错误。我有一种感觉,这是因为我没有将其作为批处理/异步请求执行,但我似乎无法找到专门用于在 Python 中批量创建活动的简单说明。任何帮助将不胜感激!

我已准备好所有广告系列详细信息并准备好放入 Google 表格中,然后我的脚本会读取该表格(使用 pygsheets)并尝试创建广告系列。到目前为止,它是这样的:

from facebookads.adobjects.campaign import Campaign
from facebookads.adobjects.adaccount import AdAccount
from facebookads.api import FacebookAdsApi
from facebookads.exceptions import FacebookRequestError
import time
import pygsheets

FacebookAdsApi.init(access_token=xxx)
gc = pygsheets.authorize(service_file='xxx/client_secret.json')

sheet = gc.open('Campaign Prep')
tab1 = sheet.worksheet_by_title('Input')
tab2 = sheet.worksheet_by_title('Output')
# gets range size, offsetting it by 1 to account for the range starting on row 2
row_range = len(tab1.get_values('A1', 'A', returnas='matrix', majdim='ROWS', include_empty=False))+1
# finds first empty row in the output sheet
start_row = len(tab2.get_values('A1', 'A', returnas='matrix', majdim='ROWS', include_empty=False))

def create_campaigns(row):
    campaign = Campaign(parent_id=row[6])
    campaign.update({
        Campaign.Field.name: row[7],
        Campaign.Field.objective: row[9],
        Campaign.Field.buying_type: row[10],
        })
    c = campaign.remote_create(params={'status': Campaign.Status.active})
    camp_name = c['name']
    camp_id = 'cg:'+c['id']
    return camp_name, camp_id

r = start_row
# there's a header so I have the range starting at 2
for x in range(2, int(row_range)):
        r += 1
        row = tab1.get_row(x)
        camp_name, camp_id = create_campaigns(row)
        # pastes the generated campaign ID, campaign name and account id back into the sheet
        tab2.update_cells('A'+str(r)+':C'+str(r).format(r),[[camp_id, camp_name, row[6].rsplit('_',1)[1]]])

我已经尝试将它放在一个 try 循环中,如果它遇到 FacebookRequestError 让它执行 time.sleep(5) 然后继续尝试,但我仍然每隔 5 到 10 行就会遇到超时错误,它循环通过.当它不超时时它确实有效,我想我只需要找出一种方法来让它更有效地处理大批量的广告系列。

有什么想法吗?我是 Facebook API 的新手,我仍然是 Python 的新手,但我发现这些东西非常有趣!如果有人对这个脚本如何变得更好有任何建议(以及一般的 Python 建议),我很想听听! :)

【问题讨论】:

  • 旁注:如果你分解出你的工作函数,你可以将它包装到backoff(寻找这个包)装饰器中,它会重试每个步骤几次(在尝试之间休眠)。跨度>
  • 感谢太空潜水员!我肯定会考虑退避。你有理由重试吗?当我用谷歌搜索退避时,我最终在重试时发现了很多东西,所以我只是好奇这两者之间有什么区别。

标签: python python-3.x facebook-ads-api facebook-marketing-api


【解决方案1】:

你能发布实际的错误信息吗?

听起来您所描述的是您在拨打一定数量的电话后达到了速率限制。如果是这样, time.sleep(5) 就不够了。率分数会随着时间的推移而衰减,并将在 5 分钟后重置https://developers.facebook.com/docs/marketing-api/api-rate-limiting。在这种情况下,我建议在每次通话之间进行睡眠。然而,更好的选择是升级您的 API 状态。如果您这么快达到速率限制,我假设您处于开发人员级别。尝试先升级到基本版,然后升级到标准版,您应该不会遇到这些问题。 https://developers.facebook.com/docs/marketing-api/access

另外,正如您所提到的,利用 Facebook 的批处理请求 API 可能是一个好主意。 https://developers.facebook.com/docs/marketing-api/asyncrequests/v2.11

这是一个线程,其中包含使用 Python SDK 的 Batch API 示例:https://github.com/facebook/facebook-python-ads-sdk/issues/116

【讨论】:

  • 原来这是一个速率限制问题,但不是 Facebook 的问题。问题实际上出在 pygsheets 上,我在创建每个广告系列后让它插入一行,而且我的 Google API 限制非常低。我更改了脚本,因此它只是将所有内容收集到一个 df 中,然后在完成后将 df 粘贴到工作表中,这似乎可以解决问题。感谢您的链接,我仍然想查看批处理请求 API!
  • 最后一个链接,可以在github APP中打开,只能在手机上打开。如果我使用其他资源管理器,它会出现 404 page not found 错误。但无论如何,问题中的代码非常有用。我将在下一条评论中粘贴。
【解决方案2】:

我粘贴了代码 sn-p(复制自 @reaktard 粘贴的最后一个链接),感谢 github 用户 @williardx

它对我的发展帮助很大。

# ----------------------------------------------------------------------------
# Helper functions

def generate_batches(iterable, batch_size_limit):
    # This function can be found in examples/batch_utils.py
    batch = []

    for item in iterable:
        if len(batch) == batch_size_limit:
            yield batch
            batch = []
        batch.append(item)

    if len(batch):
        yield batch

def success_callback(response):
    batch_body_responses.append(response.body())

def error_callback(response):
    # Error handling here
    pass

# ----------------------------------------------------------------------------

batches = []
batch_body_responses = []
api = FacebookAdsApi.init(your_app_id, your_app_secret, your_access_token)

for ad_set_list in generate_batches(ad_sets, batch_limit):
    next_batch = api.new_batch()
    requests = [ad_set.get_insights(pending=True) for ad_set in ad_set_list]

    for req in requests:
        next_batch.add_request(req, success_callback, error_callback)
    batches.append(next_batch)

for batch_request in batches:
    batch_request.execute()
    time.sleep(5)

print batch_body_responses

【讨论】:

  • 但我在使用@williardx 方法使用批处理请求方法获取完整数据集时确实遇到了问题。我发现返回的 response.body() 被附加到列表中,在成功回调函数中,除了有用的“数据”节点之外,还有“光标、分页、之前、之后”节点。而且我找不到劫持/拦截响应结果的方法。 FacebookAdsApiBatch 方法execute 似乎不允许我做太多事情。我使用了一个对象 来调用 get_ads,使用您的批量请求方法我只获取数据子集;
  • @reaktard,你试过了吗?
猜你喜欢
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多