/
YouTube

YouTube

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


Тип статьиИнструкция
КомпетенцииJupyterLab, Python, Petl, Pandas, YouTube Data API
Необходимые праваДоступ к JupyterLab, доступ к аккаунту Google
Версии компонентовJupyter core - 4.7.1, Petl - 1.7.2 , pandas - 1.2.3, Sqlalchemy - 1.3.23,

google-api-python-client==2.2.0

Статус
БЕТА
Сложность
ЛЕГКО
Полезные ссылкиPetl, Pandas, google-api-python-client, YouTube Data API v3
Дополнительные сведенияОС Ubuntu 18.04


В данной статье рассматривается пример обработки данных, полученных с помощью YouTube Data API. Для примера, мы будем собирать общедоступную статистику канала "Аналитическая платформа Visiology".

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

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

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

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

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

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

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

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

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


Для работы нам понадобятся такие библиотеки, как: google-api-python-client, Petl, Pandas, SQLAlchemy.

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

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

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


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

    from googleapiclient.discovery import build # для получения информации по API
    import petl as etl # для загрузки и обработки данных
    import pandas as pd # для выгрузки таблицы в postgresql
    import sqlalchemy # для создания подключения к базе данных
    import re # регулярные выражение
  3. Укажем YouTube Data API Key, который можно получить следуя документации (в данном примере он изменен на несуществующий). Также создадим объект youtube от YouTube Data, чтобы потом, обращаясь к нему, получать интересующую нас информацию.

    youTubeApiKey = 'BIzaSySxCQe1HesNWugdqXRDXb3LLgdzAv_4bvOtzFsA' # API из аккаунта google 
    youtube = build('youtube', 'v3', developerKey=youTubeApiKey) # Создание объекта, используя YouTube Data API v3
  4. Нужно определить id канала, чтобы потом получить дополнительную информацию.
    Чтобы узнать id канала, достаточно перейти на главную страницу канала и посмотреть в URL.



    Последние символы и есть наш id.

    channel_id = 'UC8LNafdLZNKqs3lbV5xAtNA' # id канала
  5. Далее обратимся к Api YouTube и получим более детальную информацию. Конкретно нас интересует id плейлиста со всеми загруженными видео. Вызовем метод channels().list() нашего объекта youtube. В качестве параметров укажем part='contentDetails' и id = channel_id . Первый параметр означает, что мы хотим получить детальную информацию о канале, а второй - это id нашего канала.

    channel_id = 'UC8LNafdLZNKqs3lbV5xAtNA' # id канала
    content = youtube.channels().list(part='contentDetails', id = channel_id).execute() # получение детальной информации о канале


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



  6. Получим id плейлиста со всеми выгруженными видеозаписями на канале. Они находятся в ключе 'uploads' из словаря выше.

    playlistId = content['items'][0]['contentDetails']['relatedPlaylists']['uploads'] # id плейлиста загруженных видео
  7. Создадим список, в котором будем хранить информацию по всем выгруженным видео.

    allvideos = [] # список с видео
  8.  При запросе информации по видеозаписям в ответе приходит параметр pageToken. Он сообщает токен следующей страницы, в полученном ответе. Воспользуемся им, чтобы останавливать цикл, который будет добавлять информацию о видеозаписях в список.  Укажем переменную nextPage_token = None.

    nextPage_token = None
  9.  Создадим запрос к YouTube Data, воспользовавшись функцией playlistItem().list(), в качестве параметров передадим: playlistId - id плейлиста со всеми выгруженными видеозаписями (его мы определили выше); maxResults = 100 - указывает на максимальное количество тех данных, что мы хотим получить; part = 'snippet' - означает, что мы хотим получить всю информацию о видеозаписях в рамках плейлиста; pageToken = nextPage_token - при первом запросе мы не ссылаемся на следующую страницу, а указываем наш nextPage_token, который равен None. Добавим результат запроса в список allvideos. После первого запроса мы получим токен-ссылку на следующую страницу ответа. Важно понимать, что на каждой странице содержится информация о 50-ти видеозаписях

    res = youtube.playlistItems().list(playlistId = playlistId, maxResults = 100, part = 'snippet', pageToken = nextPage_token).execute()
    allvideos += res['items']
    nextPage_token = res.get('nextPageToken')


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



    Переменная allvideos содержит информацию видео с первой страницы ответа:



  10. Добавим в список все остальные видеозаписи. Т.к. последняя страница ответа не будет иметь токен следующей страницы, мы создадим цикл, который будет добавлять в наш список allvideos информацию об оставшихся видеозаписях пока этот токен существует.

    # добавление оставшихся видео в список
    while nextPage_token is not None:
        res = youtube.playlistItems().list(playlistId = playlistId, maxResults = 100, part = 'snippet', pageToken = nextPage_token).execute()
        allvideos += res['items']
        nextPage_token = res.get('nextPageToken')
  11.  Теперь нужно получить id каждого видео, чтобы в дальнейшем получать его детальную информацию. Мы можем найти его в каждом элементе списка. Воспользуемся Python функцией map(). Она позволит нам применить функцию к каждому элементу нашего списка. Поэтому в качестве параметров мы передаем ей анонимную функцию (лямбда-выражение). Анонимная функция будет получать id каждого элемента списка. Все эти id мы поместим в новый список video_ids.

    video_ids = list(map(lambda x: x['snippet']['resourceId']['videoId'], allvideos)) # получение id видео


    Результат выполнения кода выше:

  12. Создадим список, в который будем добавлять статистику по каждой видеозаписи. Чтобы получить статистику, создадим цикл, в котором будем делать запрос к YouTube Data, пользуясь функцией videos().list(). В качестве параметров передадим: id - id видеозаписи (они берутся у каждой видеозаписи из списка video_ids); part = 'statistics'  - означает, что мы хотим получать статистику по видеозаписи.

    # получение статистики видеозаписей по их id
    stats = []
    for i in range(0, len(video_ids), 40):
        res = youtube.videos().list(id=','.join(video_ids[i:i+40]), part='statistics').execute()
        stats += res['items']


    Полученные данные в переменной stats:

  13.  Чтобы получить информацию о количестве подписчиков канала, создадим запрос к YouTube Data. Воспользуемся функцией channels().list(). В качестве параметров передадим: id - id канала ; part = 'statistics'  - означает, что мы хотим получать статистку канала. 

    channel_stats = youtube.channels().list(part='statistics', id = channel_id).execute() # получение статистики канала

  14. Запишем нужные нам данные в переменную subscriberCount:

    subscriberCount = channel_stats['items'][0]['statistics']['subscriberCount'] # количество подписчиков

  15. В нашем случае, в описании к видеозаписям хранятся ссылки. Мы хотим убрать наименование протокола, чтобы не создавалась гиперссылка в дашборде. Для этого напишем функцию, которая будет искать в тексте слово, начинающееся с 'https' и заменять наименование протокола на пустое значение:



  16. Теперь можно создать список из словарей, в который поместим всю имеющуюся у нас информацию. Одна информация у нас содержится в переменной allvideos, а другая в переменной stats. Поэтому мы создадим цикл, который будет проходит по значениям двух этих переменных и записывать в наш список значения для словаря, который мы укажем.



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



    Теперь у нас есть список словарей, из которых можно с лёгкостью создать таблицу Petl.

  17. Чтобы создать таблицу воспользуемся методом fromdicts() библиотеки Petl.

    table = etl.fromdicts(data) # создание petl таблицы
  18. Добавим в таблицу столбец с количеством подписчиков канала. Для этого мы воспользуемся методом addfield() библиотеки Petl. В качестве параметров, мы передаем методу переменную с имеющейся таблицей, название нового столбца, значение нового столбца.

    table = etl.addfield(table,'subscriberCount', subscriberCount)

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



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

    table.toxlsx('YT_statistics.xlsx', mode='overwrite') # экспорт в Excel файл


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



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

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

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

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

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


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



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

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

    # экспорт в базу данных
    df.to_sql('yt_analytics', engine, index=False, if_exists='replace', dtype={
        'title': sqlalchemy.VARCHAR(100),
        'videoIDs': sqlalchemy.VARCHAR(50),
        'video_description': sqlalchemy.Text(),
        'publishedDate': sqlalchemy.Date(),
        'liked': sqlalchemy.Integer(),
        'disliked': sqlalchemy.Integer(),
        'views': sqlalchemy.Integer(),
        'comment': sqlalchemy.Integer(),
        'subscriberCount': sqlalchemy.Integer()
    })

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

    Excel таблица:


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

    1:



    2:


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

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


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



Related content

Facebook
Facebook
More like this
Конфигурация сервиса выполнения скриптов по умолчанию
Конфигурация сервиса выполнения скриптов по умолчанию
More like this
Конфигурация сервиса выполнения скриптов по умолчанию
Конфигурация сервиса выполнения скриптов по умолчанию
More like this
Конфигурация сервиса выполнения скриптов по умолчанию
Конфигурация сервиса выполнения скриптов по умолчанию
More like this
Инкрементальная загрузка
Инкрементальная загрузка
More like this
Инкрементальная загрузка
Инкрементальная загрузка
More like this