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

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

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

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

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

Puppeteer — отличная библиотека Node JS, созданная разработчиком Chrome. Это позволяет программному коду управлять браузером Chrome для перехода на веб-сайт и взаимодействия со страницами. Когда Puppeteer загружает страницу, он по умолчанию запускает Chrome в «безголовом» режиме. Хотя процесс Chrome запущен, окно браузера не видно.

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

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

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

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

1. Перейти на Амазон

2. Введите «электроинструменты» в поле поиска по ключевому слову и введите

3. Получите названия продуктов со страницы результатов

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

Совет № 1. Попросите браузер выбрать целевой компонент

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

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

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

В браузере Chrome перейдите в меню «Вид» -> «Разработчик» -> «Проверить элементы».

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

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

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

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

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

Совет №2 — Дождитесь рендеринга страницы

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

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

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

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

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

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

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

Совет № 4 — Пользовательский агент

Ваш автоматический парсер может быть заблокирован некоторыми веб-сайтами, которые могут распознать, отправлен ли запрос человеком или машиной. Вероятно, вы получите отказ со статусом 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» при отправке HTTP-запросов на сервер. Однако Chrome не отправляет User-Agent при запуске Puppeteer.

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

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

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

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

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

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

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

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

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

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

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

  1. Первый аргумент — это селектор CSS целевого элемента.
  2. Второй аргумент — это определение функции для браузера Chrome для выполнения кода.

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

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

Последние мысли

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