/
Facebook

Facebook

Ноутбук, используемый в примере:
Facebook.ipynb


Тип статьиИнструкция
КомпетенцииJupyterLab, Python, Petl, Pandas, Facebook Graph API
Необходимые праваДоступ к JupyterLab, доступ к аккаунту Facebook
Версии компонентов

Jupyter core - 4.7.1, Petl - 1.7.2, pandas - 1.2.3, Sqlalchemy - 1.3.23,

facebook-sdk - 3.1.0

Статус
ЧЕРНОВИК
СложностьНадо попотеть
Полезные ссылкиPetl, Pandas, facebook-sdk, Facebook Graph API.
Дополнительные сведенияОС Ubuntu 18.04

В данной статье рассматривается пример обработки данных, полученных с помощью Facebook Graph API. Для удобства работы с API будет использована Python библиотека Facebook Python SDK

Для обработки данных, создания таблицы и выгрузки в Excel файл будет использована библиотека Petl, т.к. она имеет более низкий порог вхождения. Но для выгрузки данных в PostgreSQL используется библиотека Pandas, т.к. в ней это реализовано более гибко и просто.

Функционал обеих библиотек схож, и вы можете использовать ту, что вам больше нравится.


Целью этого задания является получение данных с помощью Facebook Graph API для выгрузки их в платформу и построения дашборда.
Пример не является шаблонным: в каждом случае задачи разнятся, и работать с данными придется по-другому.

Вот особенности данного кейса:

  • Количество получаемых данных небольшое - порядка 80 строк, но для демонстрации правильного подхода все выгруженные и обработанные данные сохраняются в Excel файл и базу данных PostgreSQL. Для загрузки данных в платформу вы можете использовать любой из вариантов. Когда получаемых данных много - правильнее всего использовать запись в базу данных.

Здесь не рассматривается:

  • Данные будут забираться вручную. Для регулярной автоматический выгрузки необходимо настроить планировщик Chronicle.

  • Для дальнейшей загрузки в платформу можно воспользоваться стандартными средствами в платформе: “создание загрузчика” и “планы загрузки”. Всё описано в разделе документации (ссылка для версии 2.20):
    Загрузка данных и формирование структуры в аналитической базе данных ViQube

  • Подробности работы подключенных Python библиотек. Это необходимо изучать отдельно.


Для работы нам понадобятся такие библиотеки, как: Facebook Python SDK, Petl, Pandas, SQLAlchemy.

Если они у вас не установлены, то вы можете воспользоваться статьей по установке библиотек:

Установка Python библиотек

Теперь можно приступать к работе в JupyterLab.


  1. Создаем ноутбук с названием Facebook.
  2. Первым блоком подключаем все необходимые нам для работы Python библиотеки.

    import facebook # для подключения к Facebook Graph API
    
    import petl as etl # для загрузки и обработки данных
    import pandas as pd # для удобной работы с датой и выгрузки таблицы в postgresql
    
    import datetime as dt # для установления даты
    import sqlalchemy # для создания подключения к базе данных
  3. Укажем в переменную user_token токен аутентификации, который можно получить, следуя инструкции Использование API Graph.

    Обратите внимание на то, что токен действует около 3-х часов. Вы можете ознакомиться с более подробной информацией тут.

    user_token = {your_user_token}

    Где {your_user_token} - ваш токен аутентификации.

  4. Далее создадим подключение к API, чтобы в дальнейшем использовать его возможности. В качестве параметров для подключения укажем токен аутентификации и версию Graph API. В переменной pages_data мы получим информацию о странице пользователя, чей API используется.
     

    graph = facebook.GraphAPI(access_token=user_token, version="3.0")
    pages_data = graph.get_object("/me/accounts")


    Переменная pages_data содержит в себе следующую информацию:



  5. Из полученного ответа, мы можем записать в переменные токен страницы и ID страницы.

    permanent_page_token = pages_data['data'][0]['access_token']
    page_id = pages_data['data'][0]['id']
  6. Теперь мы можем получать интересующие нас данные. Для начала запросим количество людей, которые видели любой контент связанный с нашей страницей, с разбивкой по стране.

    Воспользуемся методом get_connection() библиотеки facebook-sdk.

    В качестве параметров мы указываем:
    access_token=permanent_page_token - полученный выше токен страницы;
    id=page_id - полученный выше id страницы; 
    connection_name='insights' - название подключения, в данном случае это статистика страницы;
    metric='page_impressions_by_country_unique' - интересующая нас метрика;
    date_preset='this_year' - диапазон дат, за который берется отчёт;
    period='day' - период агрегации дат;
    show_description_from_api_doc=True - добавляет в конце ответа информацию по запросу из документации.

    content_views_by_country = graph.get_connections(access_token=permanent_page_token,
                                             id=page_id,
                                             connection_name='insights',
                                             metric='page_impressions_by_country_unique',
                                             date_preset='this_year',
                                             period='day',
                                             show_description_from_api_doc=True)


    Переменная content_views_by_country содержит в себе следующую информацию:

  7. Создадим фиксированный словарь с кодами стран и их расшифровкой, они понадобятся для дальнейшей работы с таблицей. Если вы хотите получать коды и названия стран динамически (чтобы он всегда был актуален), то можете воспользоваться API REST Countries или другим доступным в Интернете методом.

    codes = {
        'AD': 'Andorra',
        'AE': 'United Arab Emirates',
        ...
        'ZW': 'Zimbabwe',
        'ZZ': 'Unknown or unspecified country',
    }
  8. Чтобы сформировать правильную таблицу Petl, нужно изменить структуру полученного ответа. Мы создадим список, в который будем добавлять дату, код страны и значение. Пройдёмся по каждому элементу списка content_views_by_country['data'][0]['values'].
    Элементом является словарь с двумя ключами - value, end_time. Значением ключа value является словарь, внутри которого ключи - это коды стран, а значения - это количество людей из этой страны.
    Внутри первого цикла создадим еще один, который будет проходить по значениям словаря value. Для каждого элемента в этом цикле мы преобразуем дату в нужный нам формат, а затем добавим в созданный ранее список все данные.

    rows = []
    for entrance in content_views_by_country['data'][0]['values']:
        for region, value in entrance['value'].items():
            date = dt.datetime.strptime(entrance['end_time'].split('T')[0], '%Y-%m-%d').strftime('%Y-%m-%d') # преобразование даты
            rows.append([date, region, value])


    Переменная rows содержит следующую информацию:

  9.  Создадим таблицу Petl, используя метод setheader(). В качестве параметров передадим ему наш список с данными и список с названиями столбцов, которые мы видеть у нашей таблицы.

    table1 = etl.setheader(rows, ['content_views_by_country_date', 'country', 'content_views_by_country_values'])


    Переменная table1 содержит следующие данные:

  10. Для более информативного отображения мы добавим в таблицу столбец Country, в который поместим расшифровку кодов стран из столбца country. Воспользуемся методом addfield() библиотеки Petl. Этот метод в качестве параметров принимает переменную, из которой строится таблица (нашем случае это переменная table1), название нового столбца, и значение, которым будет заполнен столбец. В качестве этого значения можно передать анонимную функцию (лямбда выражение). У нашей функции в качестве переменной x - код страны. Мы будем использовать словарный метод get(), передадим ему переменную x. Функция будет искать в нашем словаре codes ключи из столбца country и возвращать значения по этим ключам. Эти значения мы и запишем в новый столбец Country.

    table1 = etl.addfield(table1, 'Country', lambda x: codes.get(x['country']))


    В таблице появился новый солбец:

  11. По той же схеме, получим приблизительное число людей, которые видели любой контент связанный с нашей страницей, с разбивкой по полу и гендеру. 
    Воспользуемся тем же методом get_connection() библиотеки facebook-sdk. Передадим этому методу те же параметры, за исключением поля metric. Полю metric мы укажем значение page_impressions_by_age_gender_unique.

    content_views_by_age_gender = graph.get_connections(access_token=permanent_page_token,
                                             id=page_id,
                                             connection_name='insights',
                                             metric='page_impressions_by_age_gender_unique',
                                             date_preset='this_year',
                                             period='day',
                                             show_description_from_api_doc=True)


    Переменная content_views_by_age_gender содержит в себе следующую информацию:



  12. Также запишем данные в пустой список. Ключ гендера и возраста мы разделим на две разных строки. Для этого воспользуемся Python методом split(). В качестве разделителя укажем символ точки. Метод вернет нам список из двух элементов ( буква гендера и возраст). Затем мы соединим эти элементы, используя Python метод join(). В качестве соединителя укажем символ пробела.

    rows_by_age_gender = []
    for entrance in content_views_by_age_gender['data'][0]['values']:
        for gender, value in entrance['value'].items():
            date = dt.datetime.strptime(entrance['end_time'].split('T')[0], '%Y-%m-%d').strftime('%Y-%m-%d')
            rows_by_age_gender.append([date, ' '.join(gender.split('.')), value])


    Список rows_by_age_gender содержит следующие данные:



  13. Разделим элемент с полом и возрастом на два элемента. Для этого воспользуемся следующей конструкцией:

    new_rows_by_age_gender = []for row in rows_by_age_gender:
         new_rows_by_age_gender.append(([*row[:1], *row[1].split(), *row[2:]]))


    Список new_rows_by_age_gender содержит следующие данные:



  14. Создадим вторую таблицу, по аналогии с первой.

    table2 = etl.setheader(new_rows_by_age_gender, ['content_views_by_age_gender_date', 'gender', 'age', 'content_views_by_age_gender_value'])


  15. Для удобства расшифруем пол пользователей. Сначала создадим словарь с расшифровкой.

    genders = {
        'M': 'Мужчины',
        'F': 'Женщины',
        'U': 'Неопределен'
    }
  16. Так же, как и ранее добавим новый столбец.

    table2 = etl.addfield(table2, 'Gender', lambda x: genders.get(x['gender']))


  17. Запросим число людей, на экране которых отображались любые публикации вашей Страницы. Публикациями считаются статусы, фото, ссылки, видео и т. п. Не забываем изменить метрику на page_impressions_unique .

    page_publications_views = graph.get_connections(access_token=permanent_page_token,
                                             id=page_id,
                                             connection_name='insights',
                                             metric='page_impressions_unique',
                                             date_preset='this_year',
                                             period='day',
                                             show_description_from_api_doc=True)


  18. Добавим данные в список.

    publications_views = []
    for entrance in page_publications_views['data'][0]['values']:
        date = dt.datetime.strptime(entrance['end_time'].split('T')[0], '%Y-%m-%d').strftime('%Y-%m-%d')
        publications_views.append([date, entrance['value']])
  19. Создадим третью таблицу.

    table3 = etl.setheader(publications_views, ['publications_views_date', 'publications_views_value'])


  20. Также получим число просмотров пользователями профиля нашей страницы. Опять-таки, не забывая изменить поле метрики. В этом случае нам понадобится метрика "page_views_total".

    page_views_total = graph.get_connections(access_token=permanent_page_token,
                                             id=page_id,
                                             connection_name='insights',
                                             metric='page_views_total',
                                             date_preset='this_year',
                                             period='day',
                                             show_description_from_api_doc=True)


  21. Создадим список из полученных данных, чтобы потом создать таблицу.

    page_view = []
    for entrance in page_views_total['data'][0]['values']:
        date = dt.datetime.strptime(entrance['end_time'].split('T')[0], '%Y-%m-%d').strftime('%Y-%m-%d')
        page_view.append([date, entrance['value']])


  22. Теперь мы можем сформировать четвертую таблицу.

    table4 = etl.setheader(page_view, ['page_views_date', 'page_views_value'])




  23. Теперь объединим все имеющиеся у нас таблицы в одну. Для этого мы воспользуемся методом annex() блиблиотеки Petl. В качестве параметров передадим этому методу все наши ранее сформированные таблицы.

    table = etl.annex(table1, table2, table3, table4)


    Получим такую таблицу:



  24. Удалим два ненужных столбца "country" и "gender". Для этого воспользуемся методом cutout() блиблиотеки Petl.

    table = table.cutout('country', 'gender')
  25. Мы можем экспортировать нашу таблицу в Excel файл для дальнейшей загрузки на платформу. Для этого воспользуемся методом toxlsx() библиотеки Petl. В качестве параметров передаем методу название Excel файла и флаг mode='overwrite', который указывает, что файл будет перезаписываться при повторном запуске кода.

    table.toxlsx('facebook.xlsx', write_header=True, mode='overwrite')

    Мы получили Excel таблицу, которую можно загружать на платформу:



  26. Помимо экспорта а Excel продемонстрируем подход с сохранением данных в PostgreSQL. Установим подключение к базе данных с помощью метода create_engine() библиотеки Sqlachemy.

    engine = sqlalchemy.create_engine('postgresql://{user}:{user_password}@{url}:{port}/{database_name}') # подключение к базе данных	

    Где {user} - имя пользователя базы данных, {user_password} - пароль, {url} - адрес базы данных, {port} - порт, {database_name} - название базы данных, в которой будет создана таблица.

  27. Далее создадим объект DataFrame библиотеки Pandas из нашей таблицы Petl. Воспользуемся методом DataFrame() и укажем ему, что названия колонок - это table[0], а значения - это срез от первого элемента таблицы Petl до последнего table[1:].

    df = pd.DataFrame(columns=table[0], data=table[1:]) # создание DataFrame из petl-таблицы


    Получим таблицу Pandas:


  28. Теперь экспортируем таблицу в базу данных PostgreSQL с помощью метода to_sql() библиотеки Pandas. В параметрах передаем название таблицы, переменную подключения engine, которую определили выше, флаги index=False и if_exists='replace', и словарь с типами данных для столбцов. Флаг index=False говорит, что не нужно создавать столбец с индексами. Флаг if_exists='replace' указывает, что таблицу нужно перезаписать, если она уже существует. В словаре dtype мы указываем название столбца в качестве ключа, а в качестве значения указывается тип данных библиотеки Sqlalchemy и его длина. Типы данных можно посмотреть тут.

    Например, для столбца ‘Country’ мы укажем тип данных VARCHAR с длинной 50. Указывается такая длина, т.к. в нашем примере название страны не будет длиннее пятидесяти символов.

    # экспорт в базу данных
    df.to_sql('facebook', engine, index=False, if_exists='replace', dtype={
        'content_views_by_country_date': sqlalchemy.Date(),
        'content_views_by_country_values': sqlalchemy.Integer(),
        'Country': sqlalchemy.VARCHAR(50),
        'content_views_by_age_gender_date': sqlalchemy.Date(),
        'age' : sqlalchemy.VARCHAR(10),
        'content_views_by_age_gender_value': sqlalchemy.Integer(),
        'Gender': sqlalchemy.VARCHAR(15),
        'publications_views_date': sqlalchemy.Date(),
        'publications_views_value': sqlalchemy.Integer(),
        'page_views_date': sqlalchemy.Date(),
        'page_views_value': sqlalchemy.Integer(),
    })

    Мы получили таблицу Excel и таблицу в базе данных PostgreSQL.

    Excel таблица:



    Таблица в базе данных:

    1:



    2:



    Где 1 - это типы данных столбцов, 2 - данные таблицы.

    Так выглядит дашборд, построенный из этих данных:



    Полученные файлы можно брать и загружать в платформу через стандартный загрузчик. На этом работа в ViXtract завершена.🥳

Related content

Фильтрация числовых показателей
Фильтрация числовых показателей
More like this
Фильтрация числовых показателей
Фильтрация числовых показателей
More like this
Фильтрация числовых показателей
Фильтрация числовых показателей
More like this
Фильтрация числовых показателей
Фильтрация числовых показателей
More like this
Фильтрация числовых показателей
Фильтрация числовых показателей
More like this
Фильтрация числовых показателей
Фильтрация числовых показателей
More like this