Puppeteer
— это официальный инструмент для Chrome Headless от команды Google Chrome. После официального анонса Chrome Headless многие из стандартных отраслевых библиотек для автоматического тестирования были прекращены их сопровождающими. В том числе и PhantomJS (грустно это слышать, знаю).
ПРИМЕЧАНИЕ: в марте 2019 года команда Puppeteer выпустила также бета-версию Puppeteer-Firefox, доступную здесь.
TL;DR
В этой статье мы будем очищать Skyscanner, авторизоваться в нем, извлекать данные о рейсах с Chrome Headless
, Puppeteer
, Node
и ExpressJS
. У Skyscanner есть механизм ограничения скорости, чтобы держать вас под контролем, но этот пост даст вам несколько хороших идей о том, что такое Скрапинг с помощью Chrome Headless и Node. Вот прилагаемый репозиторий GitHub.
Репо предназначено только для личного или учебного использования. Skyscanner предоставляет несколько полезных API вместо парсинга своего сайта.
Почувствуй силу
Puppeteer — очень мощный и простой в использовании инструмент, в том числе для целей тестирования.
В этой статье мы увидим, как очистить страницу, введя некоторые входные данные и отправив несколько форм, чтобы мы могли перемещаться по веб-сайту и получать наши результаты.
Наша цель — получить стоимость авиабилетов для заданного направления и диапазона дат.
Начиная
Прежде чем мы начнем, вам необходимо установить Node 8.+.
Клонируйте этот репозиторий в свою локальную среду (это также может быть Raspberry Pi), перейдите в него и запустите: npm install
Это установит:
- Кукольник
- Puppeteer Extra (полезный плагин Puppeteer)
- ExpressJS
- InquirerJS
Попробуй
Попробуйте запустить node index-inquirer.js
: он запустит простую анкету, чтобы получить входные данные, такие как: аэропорт вылета и возврата и т. д. Затем он запустит экземпляр браузера (Puppeteer), введите данные в форму введите и распечатайте все данные в формате JSON.
Вы также можете попробовать запустить другой индекс: node index.js -h
и node index-concurrency.js
.
Первый реализован в стиле CLI, поэтому вам нужно передать все параметры с помощью аргументов.
Второй реализован с помощью ExpressJS, и он создаст конечную точку GET для взаимодействия с ним. Это решение может управлять параллелизмом, открывая новую страницу/экземпляр Puppeteer.
Как это работает
Следующий пример — простейшая реализация Puppeteer:
const puppeteer = require('puppeteer'); async function run() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.skyscanner.com'); await page.screenshot({ path: 'screenshots/skyscanner.png' }); browser.close(); } run();
ПРИМЕЧАНИЕ. API-интерфейсы Puppeteer используют обещания, поэтому нам нужно использовать как минимум ключевое слово await. Я предлагаю вам добавить также блок try catch, чтобы ловить ошибки.
Сценарий, показанный перед открытием экземпляра Puppeteer, затем откройте новую страницу и перейдите на домашнюю страницу Skyscanner. После загрузки страницы делается снимок экрана.
Снимок экрана сделан только для видимого окна просмотра. Вы можете добавить опцию fullPage: true
для получения полной страницы (это дороже с точки зрения времени и ресурсов).
Просто, не так ли?
Теперь взгляните на следующую реализацию для навигации по странице Skyscanner и авторизации на ней:
Функция signIn является асинхронной, поэтому внутри нее используется ключевое слово await.
Вход в Skyscanner — это запрос AJAX, поэтому обновлять страницу не нужно. Сценарий говорит:
- Нажмите на кнопку входа
- Сосредоточьтесь на вводе электронной почты и введите имя пользователя.
- Затем сосредоточьтесь на вводе пароля и введите мой пароль
- После этого нажмите на кнопку отправки
Если все идет хорошо, мы вошли в систему, иначе он вернет ошибку.
Как написать сценарий
Вам нужно проанализировать целевой веб-сайт, его ресурсы и его запросы, а также весь поток, который вам нужно выполнить, чтобы получить результаты.
Puppeteer — это безголовый браузер, но вы можете добавить опцию headless: false
, и он покажет вам все этапы скрипта.
Эта функция очень полезна в тестовой среде или в режиме парсинга, потому что вы можете лучше отслеживать, что происходит.
Поиск на Скайсканере
Следующий скрипт является простым примером того, что я реализовал в репозитории этой статьи:
Я сопоставил все селекторы с его функциями, например, селектор выбора даты или счетчик для взрослых/детей и так далее.
Мы просто вводим некоторые входные данные, такие как аэропорт отправления и аэропорт назначения, и нажимаем кнопку «Отправить».
Обратите внимание, что некоторые действия задерживаются, например функции типов и всплывающие элементы (waitForSelector
).
Это очень полезно, потому что элемент может быть загружен в AJAX или может быть установлен в display: none
, и Puppeteer не может справиться с этой ситуацией: нам нужно дождаться рендеринга элемента или ожидания ответа AJAX (waitForNavigation
).
Также обратите внимание, что мы делаем скриншот страницы Skyscanner, а не домашней страницы, как раньше. Вместо этого мы делаем скриншот (1600x900) отправленной страницы поиска.
На странице результатов я могу запустить функцию для получения всех данных о рейсах:
Вывод
Puppeteer — очень мощный и полезный инструмент для тестирования и очистки веб-сайта. Этому быстро научиться и легко управлять.
Скрипт, показанный в репозитории, использует некоторые функции и классы для улучшения качества кода, но использует тот же скрипт, что и в Gist.
Скрипт предназначен только для обучения.
Всегда соблюдайте политику веб-сайта и не используйте парсинг для коммерческого использования.