Узнайте, как я извлек встроенное видео из Yahoo и вставил его в код. Давайте копать!

Моя миссия казалась простой: добавить поддержку Yahoo! Japan News к популярному загрузчику встроенного видео youtube-dl . Я бы нашел источник видео (URL-адреса), отредактировал бы шаблонный код, сделал PR и готово.

Но нет. Yahoo не собирался делать это простым.

Ниже я покажу вам, как я извлек встроенный источник видео, вместе с примером кода на Python. Хорошо, выберите статью Yahoo, и давайте копать!

HTML

Как отмечается во многих учебных пособиях по извлечению встроенного видео, найти встроенный источник видео с помощью веб-инспектора браузера относительно просто. Однако для создания эффективного экстрактора, охватывающего все Yahoo! В статьях Japan News нам нужен четкий воспроизводимый путь от исходного URL до источника видео.

Во-первых, очевидное: я открываю статью и ищу в исходном коде расширения, связанные с видео, такие как «mp4» и «m3u8».

Нада. Часто слово «плеер» ассоциируется с видео, так что давайте посмотрим, работает ли это.

Ага! Внешний сценарий Javascript, embed.js. Обратите внимание на значения contentid и spaceid в параметрах, отправленных на embed.js. Они выглядят полезными. А теперь давайте проверим, что внутри.

Код, кажется, ссылается на другой сценарий player.js и включает параметр, текущая временная метка UNIX преобразована в часы.

Проверка сети

Давайте заглянем внутрь player.js с помощью Google Chrome DevTools.

player.js огромен, выглядит устрашающе и не содержит полезных mp4 или m3u8 urls.

Хорошо, давайте работать в обратном направлении и искать mp4 в запросах, которые были сделаны при загрузке страницы (возможно, вы захотите перезагрузить страницу).

Бинго! Ответ JSON с нашими m3u8 и mp4 sources. Этот ответ генерируется запросом, который мы отправили к https://feapi-yvpub.yahooapis.jp/v1/content/ со следующими параметрами:

Что такое 1602163 in …/v1/content/1602163? Это значение contentid, которое мы отметили ранее. И space_id здесь совпадает с нашим spaceid. Отлично. А что насчет appid? Посмотрим, упоминается ли его значение в других ответах.

Вот оно, жестко запрограммировано в player.script.js! И беглый просмотр других новостных статей подтверждает, что это значение используется для всех встроенных видео-запросов. На три значения меньше. Теперь поищем значение ak.

К сожалению, значение ak можно найти только в этом JSON запросе. Откуда ak?

Контрольные точки

У меня есть подозрение, что ak может быть именем объекта Javascript. Давайте поищем "ak:".

Ага! Похоже, что ak представляет собой объединение «_» и двух строк как в player.js, так и в player.script.js. Мы также видим это в player.js, переданном в функцию k.md5().

Я предполагаю, что это объединенное строковое значение преобразуется в хеш-значение md5. Но сначала мы должны выяснить, какие значения объединяются в _.

Давайте откроем player.js на вкладке «Источники» (щелкните правой кнопкой мыши внутри тела ответа и выберите «Открыть на панели источников») и добавьте точку останова после определения ak.

Затем закроем вкладки открытых файлов в разделе Источники и перезагрузим страницу.

Странный. Похоже, что это не касается этой черты. Давайте попробуем то же самое в player.script.js.

(Не забудьте щелкнуть скобки Pretty Print в левом нижнем углу после перезагрузки страницы.)

Бинго! i похоже на то же значение, что и spaceid, которое мы отметили ранее, а r - это «headlines.yahoo.co.jp», имя нашего хоста, поэтому теперь у нас есть строковое значение «2078710353_headlines.yahoo.co.jp».

Это не похоже на длинное загадочное значение ak в запросе запроса, но помните, что k.md5 вызов функции в player.js? Давайте проверим его md5 хеш-значение.

Хочешь взглянуть на это! Это то же значение, что и ak в JSON запросе запроса. Успешно справился.

Резюме

Напомним, что запрос JSON включал следующие параметры за вычетом значений thumb.

appid: dj0zaiZpPVZMTV…jcmV0Jng9YjU-

output: json

space_id: 2078710353

domain: headlines.yahoo.co.jp

ak: 40e90ec7a4ffb34260fcbb9497778731

device_type: 1100

Теперь у нас есть все уникальные значения - и, что более важно, их источники - которые требуются для выполнения JSON запроса программно в нашем коде для любой статьи. И последнее о параметрах: device_type необходим? Давай сделаем запрос без него.

Нет видеоданных. Судя по всему, так и оставим.

Краткий обзор того, как мы получили наши видеоданные.

  • URL статьи (извлеченное имя хоста)
  • Исходный HTML-код статьи (извлечены contentid и spaceid)
  • md5 генератор хешей (запущен на spaceid + «_» + хост, чтобы получить значение pk)
  • player.script.js (извлеченный идентификатор приложения)
  • Запрос к https://feapi-yvpub.yahooapis.jp/v1/content/{contentid} с нашими значениями contentid, appid, spaceid и pk.

Код

Как этот процесс извлечения может выглядеть в коде? Вот примерный пример на Python:

Обратите внимание на yahoojnews_extract(), что я включаю в запрос значения заголовков, которые соответствуют фактическим значениям в запросе, сделанном с нашей страницы, чтобы избежать подозрений. Получив JSON данные, я передаю их _parse_formats для извлечения видеоданных (URL-адресов, кадров в секунду и т. Д.) И возвращаю их вместе с другой информацией, например заголовком.

Просмотрите код извлечения, который я написал для youtube-dl здесь или скачать, и посмотрите его в действии:

$ pip install youtube-dl && youtube-dl https://news.yahoo.co.jp

Спасибо за чтение и удачного чтения!

Предоставлено: спасибо Бемму из Candy Japan за помощь в извлечении видеоданных.