CoderCastrov logo
CoderCastrov
Программирование

6 быстрых советов по созданию автоматизированного парсера веб-страниц с использованием Puppeteer

6 быстрых советов по созданию автоматизированного парсера веб-страниц с использованием Puppeteer
просмотров
7 мин чтение
#Программирование

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

Данные - это душа систем. Без данных логика системы сводится к простым ветвлениям и вычислениям. Фактически, полезные данные являются ключевым источником дохода. Например, данные о реальном времени цен на акции, сравнение цен в супермаркетах, данные о рынке недвижимости, данные о школах, такие как результаты общих экзаменов и информация о поступлении в университет и т. д. Люди готовы платить подписку за эти данные.

Благодаря широкому распространению API, множество данных можно получить и преобразовать в целевую модель данных в ваших системах с помощью HTTP-запросов и JSON-форматтеров. Однако не всю информацию можно получить через API, даже если она общедоступна на веб-сайтах.

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

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

Puppeteer - отличная библиотека Node JS, созданная разработчиком Chrome. Она позволяет программному коду управлять браузером Chrome, переходить на веб-сайт и взаимодействовать с страницами. Когда Puppeteer загружает страницу, он фактически запускает Chrome в режиме "без головы" по умолчанию. Хотя процесс Chrome работает, окно браузера не отображается.

В этой статье я покажу вам советы о том, как получать информацию с веб-страниц с помощью этой потрясающей библиотеки.

Быстрый пример

Давайте поработаем над простой задачей - поиск продуктов на Amazon по ключевому слову "электроинструменты" и извлечение названий продуктов из результатов поиска.

Если мы сделаем это сами в браузере, то это будет включать следующие 3 простых шага:

  1. Перейти на Amazon

  2. Ввести "электроинструменты" в поле поиска по ключевому слову и нажать Enter

Источник: amazon.co.uk
  1. Получить названия продуктов со страницы результатов
Источник: amazon.co.uk

Ниже приведен исходный код, который просто автоматизирует действия с помощью puppeteer. Он очень читаемый, каждая строка - это инструкция для браузера Chrome, такая как переход по URL, фокусировка на поле поиска по ключевому слову, ввод "электроинструменты" и так далее.



Совет #1 — Научите браузер выбирать целевой компонент

Выбор целевых компонентов является фундаментальным шагом. Puppeteer предоставляет функции **$()** и **$$()** для выбора одного элемента и списка элементов соответственно. Обе функции требуют CSS-селектора в качестве аргумента.

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

Давайте рассмотрим шаги по получению CSS-селектора поля ввода ключевого слова на Amazon.

В браузере Chrome перейдите в меню Вид -> Разработчик -> Инструменты разработчика.

website: amazon.co.uk

Панель инструментов разработчика отображает HTML-код в правой панели.

website: amazon.co.uk

Переместите курсор мыши на поле ввода, и соответствующий HTML-тег <input> будет выделен в правой панели. Таким образом, мы нашли кусок HTML-кода поля ввода.

website: amazon.co.uk

Затем щелкните правой кнопкой мыши на выделенном HTML-теге и выберите Копировать -> Копировать селектор. Мы получим селектор "#twotabsearchtextbox" в буфере обмена.

Чтобы проверить CSS-селектор, нажмите Ctrl + F (на Windows) или Cmd + F (на Mac OS) на панели HTML-кода, а затем вставьте "#twotabsearchtextbox" в поле поиска. Результат поиска подтверждает, что селектор работает, и целевой компонент выделен.

Теперь, когда вы вызываете эту функцию **page.$("#twotabsearchtexbox")**, вы получите элемент поля ввода ключевого слова.



Совет №2 — Ожидание загрузки страницы

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

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

Добавив waitForSelector() в строке 14, браузер будет ждать, пока целевой компонент с заданным CSS-селектором будет доступен. Также введено ожидание waitForTimeout() в строке 24 для загрузки результатов поиска перед извлечением информации.


Совет №3 — Не забывайте ожидание

Вызовы функций Puppeteer являются асинхронными. Другими словами, выполнение вызовов функций возвращает объект promise, не ожидая завершения инструкции в Chrome. В JavaScript объект promise указывает, что запрос будет выполнен в будущем. Ключевое слово await приостанавливает выполнение потока до завершения promise.

В приведенном ниже примере инструкция по фокусировке на поле поиска ключевых слов завершится неудачно. Без await функция page.focus() будет выполнена немедленно после вызова page.waitForSelector().

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


Совет №4 — User agent

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

<html>
<head>
<title>ERROR: The request could not be satisfied</title>
</head>
<body>
<h1>403 ERROR</h1>
<h2>The request could not be satisfied.</h2>
Request blocked.
We can't connect to the server for this app or website at this time. …
</body>
</html>

Хотя Puppeteer запускает Chrome и переходит по веб-сайтам, как настоящий человек, браузер Chrome, запущенный с помощью Puppeteer, отличается от обычного браузера. User agent (идентификатор пользователя) — один из примеров. Обычно браузеры встраивают информацию о клиентской машине, такую как версия ОС и название и версия программного обеспечения браузера, в заголовок под названием "User-Agent" при отправке HTTP-запросов на сервер. Однако Chrome не отправляет User-Agent, когда он запущен с помощью Puppeteer.

Возможно, эти веб-сайты проверяют наличие User-Agent, чтобы определить, является ли запрос отправителем роботом или человеком.

Фактически, такая проверка не является очень сложной. Удобно получить заголовок User-Agent. В этом примере показано, как сгенерировать случайный User-Agent с использованием библиотеки "user-agents". Сгенерированный User-Agent может быть установлен в страницу браузера Chrome перед отправкой запроса.



Совет #5 — Получение свойства элемента

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

Пример кода выше НЕ РАБОТАЕТ! В консоль будет выведено undefined.

Причина в том, что Puppeteer возвращает указатель на элемент HTML для функции $(). Чтобы получить свойство элемента, нам нужно вызвать функцию getProperty('innerText'), которая отправляет инструкцию в браузер Chrome для получения свойства innerText, а затем другую инструкцию jsonValue(), чтобы получить JSON-значение свойства.

Теперь этот код должен быть способен получить название продукта


Совет №6 — $eval() вместо $()

Вызывать 3 функции $(), getProperty() и jsonValue() только для получения текстового содержимого элемента является утомительным и неэффективным. Этот процесс медленный, так как каждый вызов функции отправляет инструкцию в браузер Chrome и затем ожидает ответа от браузера.

Помимо $(), лучше использовать $eval() для получения свойств элемента HTML. Приведенный ниже пример демонстрирует использование одной инструкции $eval(), которая указывает браузеру Chrome получить первый элемент в результате поиска и извлечь текстовое содержимое.

$eval() принимает 2 входных аргумента:

Выполнение $eval() разделено на 2 шага — выбор целевого элемента с помощью CSS-селектора, а затем передача выбранного элемента функции для извлечения значения и создания возвращаемых данных.

Использование $eval() обычно предпочтительнее $() для более простого и эффективного выполнения кода.



Заключительные мысли

Автоматизация браузера - полезный инструмент для различных целей, таких как парсинг веб-страниц и тестирование программного обеспечения. Puppeteer - потрясающая библиотека, которая предлагает интуитивно понятный и простой способ управления браузером Chrome. Несмотря на то, что кодирование для автоматизации простое, требуется время, чтобы овладеть этой техникой. Поэтому быстрые советы в статье помогут вам ускорить разработку и избежать возможных проблем. Счастливого парсинга веб-страниц.