Ноутбук, используемый в примере:
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.
- Создаем ноутбук с названием Facebook.
Первым блоком подключаем все необходимые нам для работы Python библиотеки.
import facebook # для подключения к Facebook Graph API import petl as etl # для загрузки и обработки данных import pandas as pd # для удобной работы с датой и выгрузки таблицы в postgresql import datetime as dt # для установления даты import sqlalchemy # для создания подключения к базе данных
Укажем в переменную
user_token
токен аутентификации, который можно получить, следуя инструкции Использование API Graph.Обратите внимание на то, что токен действует около 3-х часов. Вы можете ознакомиться с более подробной информацией тут.
user_token = {your_user_token}
Где {your_user_token} - ваш токен аутентификации.
Далее создадим подключение к 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
содержит в себе следующую информацию:Из полученного ответа, мы можем записать в переменные токен страницы и ID страницы.
permanent_page_token = pages_data['data'][0]['access_token'] page_id = pages_data['data'][0]['id']
Теперь мы можем получать интересующие нас данные. Для начала запросим количество людей, которые видели любой контент связанный с нашей страницей, с разбивкой по стране.
Воспользуемся методом 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
содержит в себе следующую информацию:Создадим фиксированный словарь с кодами стран и их расшифровкой, они понадобятся для дальнейшей работы с таблицей. Если вы хотите получать коды и названия стран динамически (чтобы он всегда был актуален), то можете воспользоваться API REST Countries или другим доступным в Интернете методом.
codes = { 'AD': 'Andorra', 'AE': 'United Arab Emirates', ... 'ZW': 'Zimbabwe', 'ZZ': 'Unknown or unspecified country', }
Чтобы сформировать правильную таблицу 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
содержит следующую информацию:Создадим таблицу Petl, используя метод setheader(). В качестве параметров передадим ему наш список с данными и список с названиями столбцов, которые мы видеть у нашей таблицы.
table1 = etl.setheader(rows, ['content_views_by_country_date', 'country', 'content_views_by_country_values'])
Переменнаяtable1
содержит следующие данные:Для более информативного отображения мы добавим в таблицу столбец
Country
, в который поместим расшифровку кодов стран из столбцаcountry
. Воспользуемся методом addfield() библиотеки Petl. Этот метод в качестве параметров принимает переменную, из которой строится таблица (нашем случае это переменнаяtable1
), название нового столбца, и значение, которым будет заполнен столбец. В качестве этого значения можно передать анонимную функцию (лямбда выражение). У нашей функции в качестве переменной x - код страны. Мы будем использовать словарный метод get(), передадим ему переменную x. Функция будет искать в нашем словареcodes
ключи из столбцаcountry
и возвращать значения по этим ключам. Эти значения мы и запишем в новый столбецCountry
.table1 = etl.addfield(table1, 'Country', lambda x: codes.get(x['country']))
В таблице появился новый солбец:По той же схеме, получим приблизительное число людей, которые видели любой контент связанный с нашей страницей, с разбивкой по полу и гендеру.
Воспользуемся тем же методом 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
содержит в себе следующую информацию:Также запишем данные в пустой список. Ключ гендера и возраста мы разделим на две разных строки. Для этого воспользуемся 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
содержит следующие данные:Разделим элемент с полом и возрастом на два элемента. Для этого воспользуемся следующей конструкцией:
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
содержит следующие данные:Создадим вторую таблицу, по аналогии с первой.
table2 = etl.setheader(new_rows_by_age_gender, ['content_views_by_age_gender_date', 'gender', 'age', 'content_views_by_age_gender_value'])
Для удобства расшифруем пол пользователей. Сначала создадим словарь с расшифровкой.
genders = { 'M': 'Мужчины', 'F': 'Женщины', 'U': 'Неопределен' }
Так же, как и ранее добавим новый столбец.
table2 = etl.addfield(table2, 'Gender', lambda x: genders.get(x['gender']))
Запросим число людей, на экране которых отображались любые публикации вашей Страницы. Публикациями считаются статусы, фото, ссылки, видео и т. п. Не забываем изменить метрику на
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)
Добавим данные в список.
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']])
Создадим третью таблицу.
table3 = etl.setheader(publications_views, ['publications_views_date', 'publications_views_value'])
Также получим число просмотров пользователями профиля нашей страницы. Опять-таки, не забывая изменить поле метрики. В этом случае нам понадобится метрика "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)
Создадим список из полученных данных, чтобы потом создать таблицу.
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']])
Теперь мы можем сформировать четвертую таблицу.
table4 = etl.setheader(page_view, ['page_views_date', 'page_views_value'])
Теперь объединим все имеющиеся у нас таблицы в одну. Для этого мы воспользуемся методом
annex()
блиблиотеки Petl. В качестве параметров передадим этому методу все наши ранее сформированные таблицы.table = etl.annex(table1, table2, table3, table4)
Получим такую таблицу:Удалим два ненужных столбца "country" и "gender". Для этого воспользуемся методом
cutout()
блиблиотеки Petl.table = table.cutout('country', 'gender')
Мы можем экспортировать нашу таблицу в Excel файл для дальнейшей загрузки на платформу. Для этого воспользуемся методом toxlsx() библиотеки Petl. В качестве параметров передаем методу название Excel файла и флаг mode='overwrite', который указывает, что файл будет перезаписываться при повторном запуске кода.
table.toxlsx('facebook.xlsx', write_header=True, mode='overwrite')
Мы получили Excel таблицу, которую можно загружать на платформу:
Помимо экспорта а Excel продемонстрируем подход с сохранением данных в PostgreSQL. Установим подключение к базе данных с помощью метода create_engine() библиотеки Sqlachemy.
engine = sqlalchemy.create_engine('postgresql://{user}:{user_password}@{url}:{port}/{database_name}') # подключение к базе данных
Где {user} - имя пользователя базы данных, {user_password} - пароль, {url} - адрес базы данных, {port} - порт, {database_name} - название базы данных, в которой будет создана таблица.
Далее создадим объект DataFrame библиотеки Pandas из нашей таблицы Petl. Воспользуемся методом DataFrame() и укажем ему, что названия колонок - это table[0], а значения - это срез от первого элемента таблицы Petl до последнего table[1:].
df = pd.DataFrame(columns=table[0], data=table[1:]) # создание DataFrame из petl-таблицы
Получим таблицу Pandas:Теперь экспортируем таблицу в базу данных 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 завершена.🥳