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.

Скрипт предназначен только для обучения.

Всегда соблюдайте политику веб-сайта и не используйте парсинг для коммерческого использования.