Поиск видео на YouTube с помощью Python [6 строк кода]

Мне было интересно, как можно использовать Python для поиска видео на YouTube, не делая этого самостоятельно.

И это было довольно просто!

Это одна из вещей, которые мне нравятся в Python: он позволяет создавать программы быстро и с помощью всего нескольких строк кода.

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

Как работает поиск YouTube

Прежде всего, чтобы иметь возможность искать видео с помощью программы, нам необходимо понимать структуру URL, используемую Youtube при поиске видео.

Если я ищу «Моцарт» непосредственно на YouTube, меня перенаправляют на следующий URL-адрес:

https://www.youtube.com/results?search_query=mozart

Таким образом, единственная часть URL, которая меняется, — это поисковый запрос.

Давайте начнем создавать простую программу на Python, которая выполняет этот конкретный поиск и возвращает HTML-код с YouTube.

Пакет urllib

Основной пакет, используемый в Python для работы с URL-адресами, — это urllib, и он включает в себя несколько модулей. Нас интересует urllib.request, который можно использовать для открытия и чтения URL-адресов.

Я воспользуюсь urllib.request, чтобы получить HTML-код страницы результатов поиска на YouTube и распечатать его HTML-код.

Программы Python могут получить доступ к коду в другом модуле с помощью оператора import, поэтому давайте:

  1. Импортируем urllib.request в нашу программу.
  2. Используйте функцию urlopen модуля urllib.request для получения HTML-кода страницы поиска YouTube.
  3. Распечатайте HTML-код страницы.

Для URL-адресов HTTP и HTTPS функция urlopen возвращает объект http.client.HTTPResponse, тело которого можно прочитать с помощью метода read().

Функция urlopen возвращает объект bytes, поскольку urlopen не может узнать кодировку потока, который он получает от HTTP-сервера. По этой причине вам также нужно помнить о необходимости декодировать объект bytes из метода read() в строку с помощью метода decode().

import urllib.request

html = urllib.request.urlopen("https://www.youtube.com/results?search_query=mozart")
print(html.read().decode())

Вот фрагмент HTML страницы, напечатанной нашей программой…

Я показываю вам часть HTML-кода, на которой мы сосредоточимся, чтобы определить URL-адрес видео на странице результатов поиска:

<div class="yt-lockup-content">
<h3 class="yt-lockup-title ">
<a href="/watch?v=ULihXz-MHH8" class="yt-uix-tile-link yt-ui-ellipsis yt-ui-ellipsis-2 yt-uix-sessionlink spf-link " data-sessionlink="itct=CHMQ3DAYCyITCP_O6sPq9OgCFVUMFgodouUKPjIGc2VhcmNoUgZtb3phcnSaAQMQ9CQ"  title="Sylvia Schwartz: Mozart - Duet Papageno &amp; Papagena from &quot;Die Zauberflöte&quot; (with Thomas Quasthoff)" rel="spf-prefetch" aria-describedby="description-id-143900" dir="ltr">Sylvia Schwartz: Mozart - Duet Papageno &amp; Papagena from &quot;Die Zauberflöte&quot; (with Thomas Quasthoff)</a>

В третьей строке HTML-кода выше вы можете увидеть:

href="/watch?v=ULihXz-MHH8"

Почему мы рассматриваем эту часть HTML?

Если я нажму на любое видео на YouTube, я буду перенаправлен на URL-адрес в следующем формате:

https://www.youtube.com/watch?v=ULihXz-MHH8

Видите ли вы последнюю часть URL-адреса?

ULihXz-MHH8 — уникальный идентификатор для данного видео, идентификатор видео YouTube состоит из 11 символов.

Итак, чтобы получить URL-адрес каждого видео на странице результатов поиска YouTube, мне нужно найти вхождения, похожие на то, что мы видели выше.

Как нам это сделать?

Поиск шаблона в HTML с использованием регулярных выражений

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

Регулярное выражение (также известное как regex) — это последовательность символов, определяющая шаблон поиска.

В этом случае последовательность символов следующая:

/watch?v=<11_characters_identifier>

Модуль, используемый в Python для регулярных выражений, называется re. Подробнее об этом модуле можно узнать здесь.

Для программы, которую мы создаем, нам нужно знать только одну конкретную функцию этого модуля: findall.

Функция findall возвращает все непересекающиеся совпадения для определенного шаблона в строке (HTML-содержимое страницы результатов поиска YouTube).

Общий синтаксис функции findall:

re.findall(pattern, string)

Примечание: шаблоны регулярных выражений в Python начинаются с буквы «r».

Я объясню шаблоны регулярных выражений в другой статье, а сейчас мы просто хотим сосредоточиться на регулярном выражении, необходимом для поиска идентификаторов видео YouTube в HTML-коде страницы результатов поиска.

И снова это строка, которую мы ищем:

/watch?v=<11_characters_identifier>

А вот шаблон регулярного выражения:

r"watch\?v=(\S{11})"

Итак, давайте объясним:

  • r: как упоминалось ранее, мы используем его для определения шаблонов регулярных выражений.
  • Обратная косая черта (\): используется для экранирования специальных символов, таких как вопросительный знак (?).
  • \S: соответствует любому символу, не являющемуся пробелом.
  • {11}: указывает, что должно быть сопоставлено ровно 11 копий предыдущего регулярного выражения. В этом случае \S.
  • круглые скобки (…): указывают начало и конец группы. Мы используем группу, чтобы определить, что должно возвращать регулярное выражение, в данном случае только вхождения 11-символьных идентификаторов (исключая начальную часть… /watch?v=.

Пришло время обновить наш код Python

На данный момент мы написали следующий код Python:

import urllib.request

html = urllib.request.urlopen("https://www.youtube.com/results?search_query=mozart")
print(html.read().decode())

Следующим шагом будет добавление строки, которая с помощью функции findall идентифицирует искомый нами шаблон:

import urllib.request
import re

html = urllib.request.urlopen("https://www.youtube.com/results?search_query=mozart")
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
print(video_ids)

Вот результат работы скрипта:

['shoVsQhou-8', 'shoVsQhou-8', 'Rb0UmrCXxVA', 'Rb0UmrCXxVA', 'iUohO2MSot8', 'iUohO2MSot8', 'QEDZd066a2k', 'QEDZd066a2k', 'QHl6wYCwlcQ', 'QHl6wYCwlcQ',
......
(not all identifiers included to keep the output small)
...
'FpK1tjbeeA0', 'FpK1tjbeeA0', 'sjTLIW-qx_A', 'sjTLIW-qx_A', 'pB2p_r5Gvs8']

По сути, мы получаем список video_ids, содержащий все 11-символьные идентификаторы на странице результатов поиска YouTube.

Наконец, мы можем получить полный URL-адрес видео следующим образом:

"https://www.youtube.com/watch?v="+video_ids[i]

где индекс i позволяет выбрать любой элемент в списке video_ids. Чтобы выбрать первый результат, мы можем использовать video_ids[0].

Итак, вот версия программы, которая выводит URL первого результата поиска на YouTube:

import urllib.request
import re

search_keyword="mozart"
html = urllib.request.urlopen("https://www.youtube.com/results?search_query="+search_keyword)
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
print("https://www.youtube.com/watch?v="+video_ids[0])

А это вывод нашей программы, URL первого видео в результатах поиска Youtube по запросу «моцарт»:

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

Как видите, я сохранил значение «mozart» в переменной search_keyword.

Теперь предположим, что я хочу найти «пианино Моцарта»…

Вот что происходит, когда я заменяю значение переменной search_keyword и запускаю программу. Я получаю следующую ошибку:

http.client.InvalidURL: URL can't contain control characters. '/results?search_query=mozart piano' (found at least ' ')

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

Как бы вы обновили его для поддержки нескольких терминов?

Я предоставлю вам возможность решить этот вопрос! 🙂

Заключение

В этой статье мы рассмотрели многое, а также у вас есть интересная программа, которую вы можете расширить по своему усмотрению.

Итак, давайте повторим то, что я объяснил:

  • Пакет urllib и модуль urllib.request.
  • Регулярные выражения в Python.
  • Как использовать программу Python для поиска на YouTube.

Все ясно? 🙂