Collecting Data on Facebook Ad Campaigns

Время чтения текста – 8 минут

Let’s find out how to obtain data on costs, ad clicks, and impressions on Facebook.

from facebook_business.api import FacebookAdsApi
from facebook_business.exceptions import FacebookRequestError
from facebook_business.adobjects.adaccount import AdAccount
from facebook_business.adobjects.adreportrun import AdReportRun
from facebook_business.adobjects.adsinsights import AdsInsights
from facebook_business.adobjects.campaign import Campaign
from facebook_business.adobjects.adset import AdSet
from facebook_business.adobjects.adaccountuser import AdAccountUser as AdUser
from facebook_business import adobjects
from matplotlib import pyplot as plt
from pandas import DataFrame
import time

Getting the API Key
First thing we need to do before working with Facebook API is to create a Facebook App. Go to https://developers.facebook.com — My Apps — Create App. Type in your app name, your email, and click «Create App ID».

After all the steps have done right you will see the App Dashboard. Choose Settings — Basic, copy your App ID and your App Secret. We will need this data for authentication process later.

Now click Tools — Graph API Explorer and we will find ourselves in the token creation menu.

These tokens can be generated for different needs, we need to set access rights for our token. We’ll need ads_management – this right allows to get information about ad campaigns for your Facebook account. Add it and click «Generate Access Token».

Be careful – the user access token provides only a temporary access and expires after 1-2 hours. If you want to get a long-lived token click the blue button to open Access Token Info -- Open in Access Token Tool. You will see a new page with the «Extend Access Token» button, click it and a new long-lived Access Token will be generated for a period of 60 days.

Writing the Script

Now we need to create 3 variables, assign them to our Access Token, App ID and App Secret respectively. Log in using the init() method of FacebooksAdsApi Class and add a user. The get_ad_accounts() method returns data on all our ad accounts as a dictionary. We can get the same data using the get_campaigns() method instead.

my_access_token = ''
my_app_id = ''
my_app_secret = ''
FacebookAdsApi.init(my_app_id, my_app_secret, my_access_token)

me = AdUser(fbid='me')
my_accounts = list(me.get_ad_accounts())
my_accounts

my_account = my_accounts[0]
campaigns = my_account.get_campaigns()
print(campaigns)

Let’s retrieve the amount spent using my_account. We’ll use the api_get() method and pass AdAccount.Field.amount_spent in the fields parameter. Now, to receive the data we need some math:
divide my_account by 100 to see a whole number. The expenses will be displayed in your account currency, in our case it’s RUB. The main purpose of our actions – obtaining data on the costs of ad campaigns for further analysis:

my_account.api_get(fields=[AdAccount.Field.amount_spent])
print(int(my_account[AdAccount.Field.amount_spent])/100)

The next step will be creating two functions. The first one will send asynchronous queries to Facebook and return results. The second function forms these queries and passes them in the first function. As a result, we will get a list of dictionaries.

count = 0

def wait_for_async_job(async_job):
    global count
    async_job = async_job.api_get()
    while async_job[AdReportRun.Field.async_status] != 'Job Completed' or async_job[
        AdReportRun.Field.async_percent_completion] < 100:
        time.sleep(2)
        async_job = async_job.api_get()
    else:
        print("Job " + str(count) + " completed")
        count += 1
    return async_job.get_result(params={"limit": 1000})

def get_insights(account, date_preset='last_3d'):
    account = AdAccount(account["id"])
    i_async_job = account.get_insights(
        params={
            'level': 'ad',
            'date_preset': date_preset,
            'time_increment': 1},
            fields=fields,
            is_async=True)
    results = [dict(item) for item in wait_for_async_job(i_async_job)]
    return results

The following step is to get data on costs. We need the data for all time, therefore create the variable date_preset, set its value to lifetime. Call the get_insights() function for every account, and assign the output to insights_lists.
Create a DataFrame and extract the relevant data from the insights_lists, that’s campaign’s id, number of clicks, costs and impressions.

elem_insights = []
insights_lists = []
date_preset = 'last_year'
for elem in my_accounts:
            elem_insights = get_insights(elem, date_preset)
            insights_lists.append(elem_insights)

insight_campaign_id_list = []
insight_clicks_list = []
insight_spend_list = []
insight_impressions_list = []
insight_date_start_list = []
insight_date_stop_list = []
for elem1 in insights_lists:
    for elem2 in elem1:
        insight_campaign_id_list.append(int(elem2['campaign_id']))
        insight_clicks_list.append(int(elem2['clicks']))
        insight_spend_list.append(float(elem2['spend']))
        insight_impressions_list.append(int(elem2['impressions']))
        insight_date_start_list.append(elem2['date_start'])
        insight_date_stop_list.append(elem2['date_stop'])

df = DataFrame()
df['campaign_id'] = insight_campaign_id_list
df['clicks'] = insight_clicks_list
df['spend'] = insight_spend_list
df['impressions'] = insight_impressions_list
df['date_start'] = insight_date_start_list
df['date_stop'] = insight_date_stop_list

We’ll get the following DataFrame:

Let’s summarize this data – group it by campaigns and calculate the sum for each group. Pandas have build-in group() and sum() methods for it, just keep in mind which column to group by.

df.groupby(['campaign_id']).sum()

Now, plot two graphs  – by the number of impressions and clicks relative to the dates. We’ll use the rcParams attribute to set parameters for the graphs.

plt.rcParams['figure.figsize'] = [20, 5]
plt.plot(df.date_start.str.replace('2019-', ''), df.clicks)
plt.rcParams['figure.figsize'] = [20, 5]
plt.plot(df.date_start.str.replace('2019-', ''), df.impressions)

That’s it! Now we have the data on costs, ad impressions and clicks. In the next article, we will explain how to upload it in JSON format and pass it to Redash for further analysis and visualization.

Share
Send
Pin
 2254   2020   data analytics   facebook   python
Popular