Как выполнить парсинг YouTube на Python

Узнайте, как выполнить парсинг YouTube с помощью Python, из этого пошагового руководства.
7 min read
how to scrape youtube with python blog

Из этого пошагового руководства вы узнаете, как выполнять веб-парсинг YouTube с помощью Python

В этом руководстве рассматриваются следующие темы:

YouTube API по сравнению с парсингом YouTube

YouTube Data API — это официальный инструмент для получения данных с платформы, включая информацию о видео, плейлистах и авторах контента. Однако есть как минимум три веские причины, по которым парсинг YouTube лучше, чем использование исключительно API данного сервиса:

  • Гибкость и настройка. С помощью сборщика данных YouTube можно настроить код так, чтобы выбирать только нужные вам данные. Этот уровень настройки помогает собирать точную информацию для вашего конкретного варианта использования. В отличие от этого API предоставляет доступ только к предопределенным данным.
  • Доступ к неофициальным данным. API дает доступ к определенным наборам данных, выбранным YouTube. Это означает, что некоторые данные, которые вы сейчас используете, могут стать недоступными в будущем. Веб-парсинг напротив позволяет получить любую дополнительную информацию, доступную на веб-сайте YouTube, даже если она не доступна через API.
  • Никаких ограничений. Скорость использования YouTube API ограничена. Частота и объем запросов, которые вы можете делать за конкретный период времени, не должны превышать ограничения. Взаимодействуя напрямую с платформой, вы можете обойти любые ограничения.
    Какие данные можно собирать при парсинге YouTube

Основные поля данных для парсинга YouTube

  • Метаданные видео:
    • Заголовок
    • Описание
    • Просмотры
    • Лайки
    • Продолжительность
    • Дата публикации
    • Канал
  • Профили пользователей:
    • Имя пользователя
    • Описание пользователя
    • Подписчики
    • Количество видео
    • Плейлисты
  • Другое:
    • Комментарии
    • Похожие видео

Как объяснялось выше, лучше всего получать эти данные с помощью специального парсера. Но какой язык программирования выбрать?

Python — один из самых популярных языков для веб-парсинга благодаря простому синтаксису и богатой экосистеме библиотек. Его универсальность, удобочитаемость и широкая поддержка сообщества делают его отличным вариантом для парсинга. Ознакомьтесь с нашим подробным руководством, чтобы приступить к веб-парсингу с помощью Python.

Парсинг YouTube с помощью Selenium

Выполняйте указания этого руководства, чтобы написать скрипт Python для веб-парсинга YouTube.

Шаг 1. Настройка

Перед написанием кода необходимо выполнить следующие предварительные условия:

Вы можете инициализировать проект Python с виртуальной средой с помощью следующих команд:

mkdir youtube-scraper
cd youtube-scraper
python -m venv env

Созданный выше каталог youtube-scraper представляет собой папку проекта для вашего скрипта Python.

Откройте его в IDE, создайте файл scraper.py и инициализируйте его следующим образом:

print('Hello, World!')

На данный момент этот файл представляет собой образец скрипта, который печатает только «Hello, World!», но скоро он будет содержать логику парсинга.

Убедитесь, что скрипт работает, нажав кнопку запуска в IDE или используя:

python scraper.py

В терминале вы должны увидеть:

Hello, World!

Отлично, теперь у вас есть проект Python для вашего парсера YouTube.

Шаг 2. Выбор и установка библиотек парсинга

Если вы регулярно посещаете YouTube, вы заметите, что это очень интерактивная платформа. На основе операций кликов и прокрутки сайт динамически загружает и отображает данные. Это означает, что в своей работе YouTube в значительной степени полагается на JavaScript.

Для парсинга YouTube требуется инструмент, который может отображать веб-страницы в браузере, такой как Selenium! Этот инструмент дает возможность парсинга динамических веб-сайтов на Python, что позволяет автоматически выполнять задачи на веб-сайтах в браузере.

Добавьте пакеты Selenium и Webdriver Manager в зависимости вашего проекта с помощью:

pip install selenium webdriver-manager

Установка может занять некоторое время, поэтому наберитесь терпения.

webdriver-manager не является строго обязательным, но он упрощает управление веб-драйверами в Selenium. Благодаря этому вам не придется вручную загружать, устанавливать и настраивать веб-драйверы.

Начните работу с Selenium в scraper.py:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options

# initialize a web driver instance to control a Chrome window
# in headless mode
options = Options()
options.add_argument('--headless=new')

driver = webdriver.Chrome(
    service=ChromeService(ChromeDriverManager().install()),
    options=options
)

# scraping logic...

# close the browser and free up the resources
driver.quit()

Этот скрипт создает инстанс Chrome WebDriver — объекта, с помощью которого он программно управляет окном Chrome.

По умолчанию Selenium запускает браузер с пользовательским интерфейсом. Хотя это полезно для отладки, поскольку вы можете в реальном времени увидеть, что делает автоматический скрипт на странице, для этого требуется много ресурсов. По этой причине вам следует настроить Chrome для работы в режиме headless (без интерфейса). С помощью опции --headless=new в фоне запускается управляемый экземпляр браузера без пользовательского интерфейса.

Великолепно! Пора задать логику парсинга!

Шаг 3. Подключение к YouTube

Чтобы выполнять веб-парсинг на YouTube, сначала необходимо выбрать видео для извлечения данных. Из этого руководства вы узнаете, как выполнить парсинг последних видео из канала Bright Data на YouTube. Имейте в виду, что подойдет любое другое видео.

Вот страница YouTube, выбранная в качестве целевой:

https://www.youtube.com/watch?v=kuDuJWvho7Q

Это видео о веб-парсинге под названием «Знакомство со Scraping Browser | Bright Data».

Сохраните строку URL в переменной Python:

url = 'https://www.youtube.com/watch?v=kuDuJWvho7Q'

Теперь вы можете дать Selenium команду подключиться к целевой странице следующим образом:

driver.get(url)

Функция get() дает управляемому браузеру инструкцию посетить страницу, идентифицированную по URL-адресу, переданному в качестве параметра.

На данный момент ваш парсер YouTube выглядит так:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options

# initialize a web driver instance to control a Chrome window
# in headless mode
options = Options()
options.add_argument('--headless=new')

driver = webdriver.Chrome(
    service=ChromeService(ChromeDriverManager().install()),
    options=options
)

# the URL of the target page
url = 'https://www.youtube.com/watch?v=kuDuJWvho7Q'
# visit the target page in the controlled browser
driver.get(url)

# close the browser and free up the resources
driver.quit()

Если вы запустите скрипт, он откроет окно браузера ниже на долю секунды, а затем закроет его в связи с выполнением инструкции quit():

Прежде чем перейти к изображению YouTube

Обратите внимание на сообщение «Chrome управляется программным обеспечением для автоматического тестирования», которое подтверждает правильную работу Selenium в Chrome.

Шаг 4. Просмотр кода целевой страницы

Взгляните на предыдущий скриншот. Когда вы впервые открываете YouTube, появляется диалоговое окно согласия. Чтобы получить доступ к данным на странице, вы должны сначала закрыть ее, нажав кнопку «Принять все». Давайте узнаем, как это сделать!

Чтобы создать новый сеанс браузера, откройте YouTube в режиме инкогнито. Нажмите правой кнопкой мыши на модальном окне согласия и выберите «Просмотреть код». Откроется раздел Chrome DevTools:

Инструменты для разработчиков youtube

Обратите внимание, что диалоговое окно имеет атрибут id. Эта информация полезна для определения эффективной стратегии выбора в Selenium.

Аналогичным образом просмотрите код кнопки «Принять все»:

Это вторая кнопка, идентифицированная селектором CSS ниже:

.eom-buttons button.yt-spec-button-shape-next

Соберите все это вместе и используйте следующие строки кода, чтобы разобраться с политикой использования файлов cookie YouTube в Selenium:

try:
    # wait up to 15 seconds for the consent dialog to show up
    consent_overlay = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.ID, 'dialog'))
    )

    # select the consent option buttons
    consent_buttons = consent_overlay.find_elements(By.CSS_SELECTOR, '.eom-buttons button.yt-spec-button-shape-next')
    if len(consent_buttons) > 1:
        # retrieve and click the 'Accept all' button
        accept_all_button = consent_buttons[1]
        accept_all_button.click()
except TimeoutException:
    print('Cookie modal missing')

Модальное окно согласия загружается динамически, и его отображение может занять некоторое время. Вот почему вам нужно использовать WebDriverWait, чтобы дождаться наступления ожидаемого состояния. Если за указанный период тайм-аута ничего не происходит, возникает исключение TimeoutException. YouTube работает довольно медленно, поэтому рекомендуется использовать тайм-ауты более 10 секунд.

Поскольку YouTube постоянно меняет свои правила, диалоговое окно может не отображаться в определенных странах или ситуациях. Поэтому обработайте исключение с помощью try-catch для предотвращения ошибки скрипта в случае отсутствия модального окна.

Чтобы скрипт заработал, не забудьте добавить следующий импорт:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common import TimeoutException

После нажатия кнопки «Принять все» YouTube требуется некоторое время для динамического повторного рендеринга страницы:

В течение этого периода вы не можете работать со страницей в Selenium. Если вы попытаетесь выбрать элемент HTML, вы получите сообщение об ошибке «ссылка на устаревший элемент» (stale element reference). Оно выдается потому, что DOM сильно меняется в этом процессе.

Как вы можете видеть, элемент заголовка содержит серую строку. Просмотрев код этого элемента, вы увидите:

Хорошим индикатором момента завершения загрузки страницы является ожидание появления элемента заголовка:

# wait for YouTube to load the page data
WebDriverWait(driver, 15).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, 'h1.ytd-watch-metadata'))
)

Вы готовы к парсингу YouTube на Python. Продолжайте анализировать код целевого сайта в DevTools и ознакомьтесь с его DOM.

Шаг 5. Извлечение данных YouTube

Во-первых, вам нужна структура данных, в которой будет храниться информация, полученная в ходе парсинга. Инициализируйте словарь Python с помощью следующего:

video = {}

Как вы уже заметили на предыдущем шаге, самая интересная информация находится в разделе под видеоплеером:

С помощью CSS-селектора h1.ytd-watch-metadata вы можете получить заголовок видео:

title = driver \
    .find_element(By.CSS_SELECTOR, 'h1.ytd-watch-metadata') \
    .text

Прямо под заголовком находится элемент HTML с информацией о канале:

Он идентифицируется id-атрибутом «владелец» (owner), и вы можете получить все данные из него с помощью следующего:

# dictionary where to store the channel info
channel = {}

# scrape the channel info attributes
channel_element = driver \
    .find_element(By.ID, 'owner')

channel_url = channel_element \
              .find_element(By.CSS_SELECTOR, 'a.yt-simple-endpoint') \
              .get_attribute('href')
channel_name = channel_element \
              .find_element(By.ID, 'channel-name') \
              .text
channel_image = channel_element \
              .find_element(By.ID, 'img') \
              .get_attribute('src')
channel_subs = channel_element \
              .find_element(By.ID, 'owner-sub-count') \
              .text \
              .replace(' subscribers', '')

channel['url'] = channel_url
channel['name'] = channel_name
channel['image'] = channel_image
channel['subs'] = channel_subs

Еще ниже находится описание видео. У этого компонента сложное поведение, так как он показывает разные данные в зависимости от того, закрыт он или открыт.

Нажмите на него для дсотупа к полным данным и их просмотра:

driver.find_element(By.ID, 'description-inline-expander').click()

Вы должны получить доступ к информационному элементу с расширенным описанием:

Извлеките просмотры видео и дату публикации с помощью следующих команд:

info_container_elements = driver \
    .find_elements(By.CSS_SELECTOR, '#info-container span')

views = info_container_elements[0] \
    .text \
    .replace(' views', '')
publication_date = info_container_elements[2] \
    .text

Текстовое описание, связанное с видео, содержится в следующем дочернем элементе:

Выполните его парсинг с помощью:

description = driver \
    .find_element(By.CSS_SELECTOR, '#description-inline-expander .ytd-text-inline-expander span') \
    .text

Затем просмотрите код кнопки «Нравится»:

Получите данные о количестве лайков с помощью следующего:

likes = driver \
    .find_element(By.ID, 'segmented-like-button') \
    .text

Наконец, не забудьте вставить данные парсинга в словарь video («видео»):

video['url'] = url
video['title'] = title
video['channel'] = channel
video['views'] = views
video['publication_date'] = publication_date
video['description'] = description
video['likes'] = likes

Замечательно! Вы только что выполнили веб-парсинг на Python!

Шаг 6. Экспорт данных парсинга в JSON

Интересующие вас данные теперь хранятся в словаре Python, но это не лучший формат для передачи их другим командам. Собранную информацию можно преобразовать в формат JSON и экспортировать в файл, содержащий всего две строки кода:

with open('video.json', 'w') as file:
    json.dump(video, file)

Этот фрагмент инициализирует файл video.json с помощью open(). Затем он использует json.dump() для записи JSON-представления словаря video («видео») в файл вывода. Ознакомьтесь с нашей статьей, чтобы узнать больше о парсинге JSON на Python.

Для достижения цели вам не нужен дополнительный зависимый объект. Все, что вам нужно, — это пакет стандартной json-библиотеки Python, который вы можете импортировать с помощью:

import json

Превосходно! Вы начали с необработанных данных, содержащихся на динамической HTML-странице, и теперь у вас есть полуструктурированные данные JSON. Пора проверить весь парсер YouTube.

Шаг 7. Заключительная сборка
Вот полный скрипт scraper.py:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common import TimeoutException
import json

# enable the headless mode
options = Options()
# options.add_argument('--headless=new')

# initialize a web driver instance to control a Chrome window
driver = webdriver.Chrome(
    service=ChromeService(ChromeDriverManager().install()),
    options=options
)

# the URL of the target page
url = 'https://www.youtube.com/watch?v=kuDuJWvho7Q'
# visit the target page in the controlled browser
driver.get(url)

try:
    # wait up to 15 seconds for the consent dialog to show up
    consent_overlay = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.ID, 'dialog'))
    )

    # select the consent option buttons
    consent_buttons = consent_overlay.find_elements(By.CSS_SELECTOR, '.eom-buttons button.yt-spec-button-shape-next')
    if len(consent_buttons) > 1:
        # retrieve and click the 'Accept all' button
        accept_all_button = consent_buttons[1]
        accept_all_button.click()
except TimeoutException:
    print('Cookie modal missing')

# wait for YouTube to load the page data
WebDriverWait(driver, 15).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, 'h1.ytd-watch-metadata'))
)

# initialize the dictionary that will contain
# the data scraped from the YouTube page
video = {}

# scraping logic
title = driver \
    .find_element(By.CSS_SELECTOR, 'h1.ytd-watch-metadata') \
    .text

# dictionary where to store the channel info
channel = {}

# scrape the channel info attributes
channel_element = driver \
    .find_element(By.ID, 'owner')

channel_url = channel_element \
              .find_element(By.CSS_SELECTOR, 'a.yt-simple-endpoint') \
              .get_attribute('href')
channel_name = channel_element \
              .find_element(By.ID, 'channel-name') \
              .text
channel_image = channel_element \
              .find_element(By.ID, 'img') \
              .get_attribute('src')
channel_subs = channel_element \
              .find_element(By.ID, 'owner-sub-count') \
              .text \
              .replace(' subscribers', '')

channel['url'] = channel_url
channel['name'] = channel_name
channel['image'] = channel_image
channel['subs'] = channel_subs

# click the description section to expand it
driver.find_element(By.ID, 'description-inline-expander').click()

info_container_elements = driver \
    .find_elements(By.CSS_SELECTOR, '#info-container span')
views = info_container_elements[0] \
    .text \
    .replace(' views', '')
publication_date = info_container_elements[2] \
    .text

description = driver \
    .find_element(By.CSS_SELECTOR, '#description-inline-expander .ytd-text-inline-expander span') \
    .text

likes = driver \
    .find_element(By.ID, 'segmented-like-button') \
    .text

video['url'] = url
video['title'] = title
video['channel'] = channel
video['views'] = views
video['publication_date'] = publication_date
video['description'] = description
video['likes'] = likes

# close the browser and free up the resources
driver.quit()

# export the scraped data to a JSON file
with open('video.json', 'w') as file:
    json.dump(video, file, indent=4)

Вы можете создать веб-парсер для сбора данных из видео YouTube, используя всего около 100 строк кода!

Запустите скрипт, и следующий файл video.json появится в корневой папке вашего проекта:

{
    "url": "https://www.youtube.com/watch?v=kuDuJWvho7Q",
    "title": "Introduction to Bright Data | Scraping Browser",
    "channel": {
        "url": "https://www.youtube.com/@BrightData",
        "name": "Bright Data",
        "image": "https://yt3.ggpht.com/_Q-FPPjoMEH_3ocfi1lTy1HBwdh7CqUfehS7G9silsQcPZX11yAGffubPO1haKyFtbxKBURT=s48-c-k-c0x00ffffff-no-rj",
        "subs": "4.65K"
    },
    "views": "116",
    "publication_date": "Jun 14, 2023",
    "description": "Welcome to our comprehensive guide on setting up and using Bright Data's Scraping Browser for efficient web data extraction. This video walks you through the process of setting up the Scraping Browser, highlighting its unique features and benefits.\n\n- Introduction to Bright Data's Scraping Browser\n- Navigating the 'Proxies and Scraping Infrastructure' page\n- Creating and Naming Your Scraping Browser\n- Explaining User Interaction, Geo-Restrictions, and IP Rate Limits\n- Breakdown of Costs for Using the Scraping Browser\n- Access Parameters and Their Importance\n- Integration Examples: Puppeteer in Node.js and Playwright in Python\n- Introduction to Web Scraping 'Today's Deals' from Amazon.com\n- Automated Data Extraction Process\n- Statistics of Data Usage\n- Benefits of Automated Web Scraping\n\nWhether you're looking to extract data behind user interactions, dealing with geo-restrictions, or IP rate limits, Bright Data's Scraping Browser provides comprehensive solutions for your needs. In this video, we also delve into a practical demonstration using Puppeteer and Python, illustrating how this browser can help you access and extract data efficiently.\n\n#BrightData #ScrapingBrowser #WebScraping #Puppeteer #Python #Nodejs #Playwright #DataExtraction",
    "likes": "3"
}

Поздравляем! Вы только что узнали, как выполнять парсинг YouTube на Python!

Заключение

Из этого руководства вы узнали, почему парсинг YouTube лучше, чем использование данных API. В частности, вы увидели пошаговое руководство по созданию парсера Python, который может извлекать данные из видео YouTube. Как показано здесь, это несложно и требует всего нескольких строк кода.

В то же время YouTube — это динамичная платформа, которая постоянно развивается, поэтому созданный здесь парсер может работать не вечно. Его поддержание в рабочем состоянии, позволяющее адаптироваться к изменениям на целевом сайте, требует много времени и усилий. Вот почему мы создали YouTube Scraper, надежное и простое в использовании решение, позволяющее без проблем получать все необходимые данные!

Кроме того, не стоит упускать из виду системы защиты от ботов Google. Selenium — отличный инструмент, но он никак не сможет справиться с передовыми технологиями защиты. Если Google решит защитить YouTube от ботов, большинство автоматических скриптов станут бесполезны. Если это произойдет, вам понадобится инструмент, который может отображать JavaScript и автоматически обрабатывать цифровые отпечатки, капчи и защиту от парсинга. К счастью, он существует и называется Scraping Browser!

Совсем не хотите заниматься веб-парсингом, но вас интересуют данные элемента? Запросите набор данных YouTube.