Давайте создадим парсер в реальном времени с помощью Python, Flask, Requests и Beautifulsoup!

Вступление

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

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



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

Отказ от ответственности: я не буду тратить слишком много времени на подробное объяснение анализа и части соскабливания. Я предполагаю, что у вас уже есть некоторые основы работы с Python, запросами и Beautifulsoup, и что вы знаете, как проверять веб-сайт для извлечения селекторов CSS.

Анализ

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

Давайте что-нибудь введем и нажмем Enter, чтобы понаблюдать за поведением веб-сайта.

Теперь мы перенаправлены на страницу результатов поиска. Здесь вы можете увидеть список всех игр, связанных с вашим поиском. В моем случае у меня есть следующее:

Если мы проверим страницу, мы заметим, что каждая строка результатов находится внутри тега ‹a› с классом search_result_row. Элементы, которые мы ищем, расположены в следующих селекторах:

gameURL: situated in the href of 'a.search_result_row'
title: text of 'span.title'
releaseDate: text of 'div.search_released'
imgURL: src of 'div.search_capsule img'
price: text of 'div.search_price span strike'
discountedPrice: text of 'div.search_price'

Еще один интересный элемент - это URL-адрес страницы.

Мы видим, что искомые термины указаны после параметра term.

Пока что, получив эти элементы, мы можем написать простой скрипт, который извлекает нужные нам данные. Вот пример файла main.py:

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

pipenv install requests beautifulsoup4
pipenv run python main.py

Преобразование в скребок реального времени

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

  1. На этом этапе клиент или интерфейс (в зависимости от ваших потребностей) выполняет запрос PUT, содержащий поисковый запрос в аргументах HTTP-сервера.
  2. HTTP-сервер получает запрос и обрабатывает его, чтобы извлечь поисковый запрос.
  3. Затем сервер отправляет запрос GET в магазин Steam, чтобы передать ему поисковый запрос.
  4. Steam отправляет на сервер свою страницу результатов поиска в формате HTML.
  5. На этом этапе сервер получает HTML-код, форматирует его для извлечения необходимых нам данных игры.
  6. После обработки данные отправляются клиенту / интерфейсу в красиво отформатированном JSON-ответе.

HTTP-сервер с Flask и Flask_restful

Flask - очень полезный фреймворк Python, предназначенный для быстрого создания веб-сервера. Flask_restful - это расширение для Flask, которое позволяет нам легко разрабатывать REST API.

Во-первых, давайте установим эти две библиотеки, выполнив следующую команду:

pipenv install Flask flask-restful

Давайте импортируем эти две библиотеки вmain.py

Теперь вы можете создать приложение Flask и объявить его в начале файла после импорта.

Давайте проведем рефакторинг парсера, который у нас был ранее, чтобы сообщить Flask, что теперь он должен быть частью ресурса и доступен через запрос PUT. Для этого нам нужно создать новый класс под названием SteamSearch (название зависит от вас), который наследуется от Resource, который мы импортируем из flask_restful. Затем мы помещаем наш код в метод с именем put, чтобы указать, что к нему можно получить доступ с помощью этого типа запроса. Окончательный результат выглядит следующим образом:

Внизу файла мы должны сказать Flask, что класс StreamSearch является частью API. Нам также необходимо указать маршрут, по которому можно запросить ресурс. Для этого можно использовать следующий код:

Строки 3 и 4 нужны просто для запуска приложения. Параметр debug=True предназначен для облегчения нашей жизни во время разработки, автоматически обновляя сервер, когда мы вносим изменения в код. Если вы хотите развернуть сервер в производственной среде, необходимо установить неправильное значение!

Последнее, что нам нужно сделать, это обработать аргумент, переданный в запросе PUT, который получает наш сервер. Этого можно добиться с помощью reqparse, который мы импортировали из flask_restful.

С помощью этого помощника мы можем определить, какие аргументы могут быть отправлены в теле запроса, каковы их типы, требуются ли они и т. Д. Вы можете добавить следующий код в самый верх метода put.

После этого шага время поиска может быть доступно в методе put через args.term. Если вам нужны другие аргументы, вы можете добавить их столько, сколько захотите, после второй строки кода примера.

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

Непосредственно перед отправкой запроса в магазин Steam мы можем добавить эти строки в наш код.

Первая строка, как я сказал ранее, отформатирует термин, если он содержит неподдерживаемые символы. Результатом этой функции будет что-то вроде term=$valueOfArgsTerm.

Затем мы передаем это значение в запрос GET, и все готово!

В итоге код должен выглядеть так:

Вы можете запустить свой HTTP-сервер с pipenv run python main.py

Попробуем сделать запрос к нашему серверу с помощью Почтальона. Результат будет таким:

Заключение

Спасибо, что прочитали эту статью! Если вы хотите немного потренироваться по этой теме, вы можете попытаться заставить свой сервер обрабатывать номер страницы результатов поиска Steam.

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