CoderCastrov logo
CoderCastrov
Парсер

Как парсить API запросы?

Как парсить API запросы?
просмотров
5 мин чтение
#Парсер

Извлекайте данные непосредственно из сетевого трафика, используя XHR (XMLHttpRequest).

Вчера я пытался помочь кому-то с задачей парсинга веб-сайта и наткнулся на интересный способ использования API для извлечения данных с определенных веб-сайтов.

Сегодня многие сайты используют фронтенд-фреймворки, которые отображают динамический контент, загружая JSON или XML файл с их бэкенда. Я покажу вам, как найти URL для доступа к этому динамическому контенту, чтобы вы могли легко парсить данные с сайта без использования BeautifulSoup, CSS-селекторов или XPath. Просто чистый, простой JSON.

Зачем парсить сетевой трафик?

Вы находитесь на платформе социальных медиа и делаете пост. Допустим, это твит. Затем ваш друг оставляет комментарий. Вместо того, чтобы делать запрос на перезагрузку всей страницы для отображения последнего комментария вашего друга, ваш браузер делает запрос только для данных, связанных с вашим постом.

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

Вот и все. Вы открываете URL-адрес веб-сайта, который вы хотите спарсить.

Вы получаете доступ к HTML. Но ничего. Данные не отображаются открыто.

Прежде чем перейти к XHR, давайте сначала поговорим о одной распространенной проблеме, с которой многие сталкиваются при парсинге страницы. Убедитесь, что вы не застряли на этом уровне, прежде чем перейти на более глубокий уровень.

Данные в скрипте не совпадают с данными в HTML

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

  • Просмотр исходного кода показывает вам HTML точно так, как его возвращает веб-сайт при первом запросе.
  • Инструменты разработчика показывают вам весь отображаемый контент, включая выполнение JavaScript и новые AJAX-запросы. Подумайте о веб-приложениях.

Возьмем простой пример, скажем, Twitter. Если вы перейдете к Просмотреть исходный код, вы увидите довольно небольшой документ, в основном загружающий необходимые файлы JavaScript. Но если вы используете Инструменты разработчика, вы увидите гораздо больше HTML-кода, так как он был загружен и отображен.

В этом случае есть шанс, что вам не хватает заголовка запроса User-Agent. Заголовок User-Agent указывает используемый браузер. Если его нет, веб-сайт может предположить, что делается автоматический запрос. Но исправить это очень просто.

Просто добавьте User-Agent современного браузера в ваши запросы.

'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'

Но это не всегда будет так просто. В большинстве случаев внутри структуры страницы не будет отображаться никаких данных. Давайте рассмотрим это поближе.

Данные даже не существуют внутри HTML

Мы будем использовать Chrome Tools, чтобы определить, какой запрос отвечает за получение данных, которые мы ищем.

Возьмем в качестве примера Airtable, так как мой друг работал над ним. В основном, это приложение позволяет командам создавать и делиться задачами.

Я ищу запрос, который приводит новые твиты на страницу панели управления. Вот шаги, которые я выполнил, чтобы найти правильный запрос:

  • Открыл вкладку Network в инструментах разработчика Chrome и нажал на XHR, чтобы видеть только такие запросы (а не CSS, изображения и т. д.).
  • Запустил новую загрузку. Ctrl+R, иногда это кнопка "Загрузить еще". В этом случае, это вызвано прокруткой вниз.
  • Просмотрел запросы, пока не нашел нужные данные в них, Ctrl+F

Теперь вы можете видеть, что есть некоторые данные, которые передаются через сеть. Если веб-сайт загружает данные динамически, обычно он использует XMLHttpRequests (XHR).

Airtable XHRs

Браузер использует API для получения данных с сервера. Именно то, что мы ищем. Здесь XHR - это GET-запрос, содержащий все данные, которые мы хотим спарсить.

Иногда вы можете просто скопировать этот URL и вставить его в другое место, и данные появятся. Но здесь система немного сложнее: для каждого запроса генерируется уникальный URL, чтобы предотвратить его парсинг. Мы рассмотрим позже, как с этим справиться.

Примечание:_ безголовый браузер отображает все данные из XHR-запросов и из содержимого, хранящегося внутри тегов <script>, потому что страница ведет себя точно так же, как в браузере. Вы можете использовать selenium, puppeteer, splash или любой другой инструмент для парсинга с помощью JS / безголового браузера. Но есть некоторые недостатки:_

  • Гораздо медленнее, чем одиночные HTTP-запросы для парсинга
  • Трудно масштабировать и выполнять параллельные запросы.

Это вариант, когда ничто другое не работает или когда требуется ввод.

Работа с POST-запросами

В нашем примере мы работали с GET-запросом.

Но что если веб-сайт использует POST-запросы, которые работают только в контексте загруженной страницы (защищенные куки, заголовки, токены..)? Тогда вы можете использовать безголовый браузер, загрузить первую страницу и отправить POST-запросы оттуда.

Такой подход можно использовать, чтобы получить отзывы о приложении из Google Play Store. На рисунке ниже вы можете увидеть хороший пример POST-запроса вместе с его данными, который отправляется для просмотра каждых 40 отзывов.

Чтобы отправить POST-запрос, мы можем использовать jQuery.ajax() и вызвать его из контекста страницы, загруженной в безголовом браузере. Чтобы получить больше 40 отзывов, вы можете итерировать параметр page (анализируя структуру URL).

XHR в этом случае возвращает HTML-данные вместо JSON, поэтому нам нужно их разобрать и использовать селекторы.

Таким образом, вы можете парсить и извлекать 4 000 отзывов для заданного приложения в Google Play Store за несколько секунд.

Как обрабатывать HTTP-ответы 429

В некоторых случаях вы получаете ответы с кодом 429 или другими ограничениями скорости. Очень вероятно, что веб-сайт понял, что вы парсите его и пытается остановить вас.

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

Заключение

Поздравляю, если вы добрались до этого момента. Путем прямого доступа к сетевому трафику веб-сайта нам удалось извлечь данные, которые невозможно получить обычным путем. Надеюсь, вы узнали что-то новое и получили удовольствие от чтения этого!


Есть вопросы?

Не стесняйтесь написать мне на amine.melbx@gmail.com,

Амин.