CoderCastrov logo
CoderCastrov
Питон

Как выполнить JavaScript с помощью Scrapy?

Как выполнить JavaScript с помощью Scrapy?
просмотров
6 мин чтение
#Питон

Узнайте, как парсить динамические веб-сайты с помощью Scrapy и Selenium, Splash и ScrapingBee middleware для браузеров без графического интерфейса

Большинство современных веб-сайтов используют клиентскую JavaScript-платформу, такую как React, Vue или Angular. Для парсинга данных с динамического веб-сайта без серверного рендеринга часто требуется выполнение кода JavaScript.

Я парсил сотни сайтов и всегда использовал Scrapy. Scrapy - популярный фреймворк для парсинга веб-сайтов на языке Python. По сравнению с другими библиотеками для парсинга на Python, такими как Beautiful Soup, Scrapy заставляет вас структурировать свой код на основе некоторых bewst practices. Взамен Scrapy заботится о параллельности, сборе статистики, кэшировании, обработке логики повторных попыток и многом другом.

Если вы новичок в Scrapy, вам, вероятно, стоит начать с прочтения этого отличного руководства, которое научит вас всем основам Scrapy.

В этой статье я сравниваю самые популярные решения для выполнения JavaScript с помощью Scrapy, рассказываю о масштабировании браузеров без графического интерфейса и представляю интеграцию с ScrapingBee API для поддержки JavaScript и ротации прокси.


Парсинг динамических веб-сайтов с помощью Scrapy

Парсинг веб-сайтов с клиентской обработкой с помощью Scrapy раньше был проблематичным. Я часто приходил к тому, чтобы анализировать запросы API в инструментах сетевого обозревателя браузера и извлекать данные из переменных JavaScript.

Хотя эти хаки могут работать на некоторых веб-сайтах, я считаю код более сложным для понимания и поддержки, чем традиционные XPATH. Но для парсинга данных с клиентской стороны напрямую из HTML вам сначала нужно выполнить код JavaScript.

Промежуточные программы Scrapy для браузеров без графического интерфейса

Браузер без графического интерфейса - это веб-браузер без графического пользовательского интерфейса. Я использовал три библиотеки для выполнения JavaScript с помощью Scrapy: scrapy-selenium, scrapy-splash и scrapy-scrapingbee.

Все три библиотеки интегрированы как промежуточные программы загрузчика Scrapy. После настройки в настройках вашего проекта, вместо того чтобы создавать обычный запрос Scrapy из ваших пауков, вы создаете SeleniumRequest, SplashRequest или ScrapingBeeRequest.

Выполнение JavaScript в Scrapy с помощью Selenium

Локально вы можете взаимодействовать с браузером без графического интерфейса с помощью промежуточного программного обеспечения scrapy-selenium. Selenium - это фреймворк для взаимодействия с браузерами, который часто используется для тестирования приложений, парсинга веб-страниц и создания скриншотов.

Для взаимодействия с браузером Selenium требуется веб-драйвер. Например, для работы с Firefox вам потребуется установить geckodriver. Затем вы можете настроить Selenium в настройках вашего проекта Scrapy.

В своих пауках вы можете использовать SeleniumRequest.

Selenium позволяет вам взаимодействовать с браузером на языке Python и JavaScript. Объект driver доступен из объекта ответа Scrapy. Иногда может быть полезно проверить HTML-код после нажатия на кнопку. Локально вы можете установить точку останова с помощью отладчика ipdb, чтобы проверить HTML-ответ.

В противном случае, с помощью объекта ответа Scrapy можно использовать XPATH и CSS-селекторы для выбора данных из HTML.

SeleniumRequest принимает некоторые дополнительные аргументы, такие как wait_time для ожидания перед возвратом ответа, wait_until для ожидания HTML-элемента, screenshot для создания скриншота и script для выполнения пользовательского JavaScript-скрипта.

В производственной среде основной проблемой scrapy-selenium является то, что нет простого способа настроить Selenium grid для запуска нескольких экземпляров браузера на удаленных машинах. Далее я сравню два решения для выполнения JavaScript с помощью Scrapy в масштабе.

Выполнение JavaScript в Scrapy с помощью Splash

Splash - это веб-браузер в виде сервиса с API. Он поддерживается Scrapinghub, основным разработчиком Scrapy, и интегрирован с Scrapy через промежуточное программное обеспечение scrapy-splash. Его также можно разместить на Scrapinghub.

Splash был создан в 2013 году, до того, как в 2017 году были выпущены другие популярные безголовые браузеры, такие как headless Chrome. С тех пор другие популярные проекты, такие как PhantomJS, были прекращены в пользу безголовых браузеров Firefox, Chrome и Safari.

Вы можете запустить экземпляр Splash локально с помощью Docker.

Настройка промежуточного программного обеспечения Splash требует добавления нескольких промежуточных программ и изменения приоритета по умолчанию HttpCompressionMiddleware в настройках вашего проекта.

Затем вы можете использовать SplashRequest с необязательными аргументами wait и lua_source.

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

Выполнение JavaScript в Scrapy с помощью ScrapingBee

ScrapingBee - это API для парсинга веб-страниц, которое обрабатывает безголовые браузеры и прокси для вас. ScrapingBee использует последнюю версию безголового Chrome и поддерживает выполнение JavaScript-скриптов.

Как и другие движки, вы можете просто установить промежуточное ПО scrapy-scrapingbee с помощью pip.

Сначала вам нужно создать учетную запись ScrapingBee, чтобы получить ключ API. Затем вы можете добавить промежуточное ПО загрузчика и установить параллелизм в соответствии с вашим планом ScrapingBee в настройках проекта.

Затем вы можете унаследовать своих пауков от ScrapingBeeSpider и использовать ScrapingBeeRequest.

ScrapingBeeRequest принимает необязательный аргумент params для выполнения js_snippet, установки пользовательской wait перед возвратом ответа или ожидания CSS или XPATH селектора в HTML-коде с помощью wait_for.

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

ScrapingBee собрал другие распространенные фрагменты JavaScript для взаимодействия с веб-сайтом в документации ScrapingBee.

Под капотом промежуточное ПО scrapy-scrapingbee преобразует исходный запрос в запрос, перенаправленный на API ScrapingBee и кодирует каждый аргумент в строку запроса URL. Конечная точка API регистрируется в журналах Scrapy, а api_key скрыт с помощью ScrapingBeeSpider.

В методе parse вашего паука response.url преобразуется промежуточным ПО в исходный URL, переданный в ScrapingBeeRequest.

Еще одним преимуществом использования ScrapingBee является возможность использования резидентных прокси в разных странах и автоматическая смена прокси с помощью следующих аргументов.

Использование кэша и параллельности в парсере Scrapy для ускорения скрапинга

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

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

Локально, при разработке парсера, вы можете использовать встроенную систему кэширования Scrapy. Она позволяет ускорить последующие запуски, так как ответы сохраняются на вашем компьютере в скрытой папке .scrapy/httpcache. Вы можете активировать HttpCacheMiddleware в настройках вашего проекта:

HTTPCACHE_ENABLED = True

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

CONCURRENT_REQUESTS = 32

При использовании ScrapingBee не забудьте установить значение параллельности в соответствии с вашим планом ScrapingBee.

Заключение

Я сравнил три промежуточных обработчика Scrapy для рендеринга и выполнения JavaScript с помощью Scrapy. Selenium позволяет взаимодействовать с веб-браузером с использованием Python во всех основных безголовых браузерах, но масштабирование может быть сложным. Splash можно запустить локально с помощью Docker или развернуть на Scrapinghub, но он зависит от собственной реализации браузера, и вам придется писать скрипты на Lua. ScrapingBee использует последнюю версию безголового браузера Chrome, позволяет выполнять пользовательские скрипты на JavaScript и также обеспечивает ротацию прокси для самых сложных сайтов для парсинга.

Ресурсы


Оригинальная публикация на сайте https://www.scrapingbee.com.