
Дебаты по поводу выбора между Playwright и Puppeteer - это большая дискуссия, поскольку они обе являются фантастическими библиотеками Node.js для автоматизации браузера. Хотя эти библиотеки делают практически одно и то же, между Puppeteer и Playwright есть несколько заметных различий.
Давайте проведем краткий экскурс в историю:
Puppeteer был создан командой разработчиков Chrome в 2017 году, чтобы компенсировать ненадежность Selenium для автоматизации браузеров. Playwright был позже запущен Microsoft и, как и Puppeteer, способен эффективно выполнять сложные тесты автоматизации в браузере. Но на этот раз они представили больше инструментов для тестирования. Так какой же из них лучше?
Давайте рассмотрим различия между Puppeteer и Playwright, чтобы понять, в чем уникальность обеих библиотек.
Playwright по сравнению с Puppeteer: в чем основные различия?
Puppeteer и Playwright - это headless-браузеры, изначально предназначенные для сквозного автоматизированного тестирования веб-приложений. Они использовались и для других целей, например, для веб-скрейпинга. Несмотря на то, что у обоих инструментов автоматизации имеются схожие юзкейсы, существуют некоторые ключевые различия:
Playwright поддерживает Python, Golang, Java, JavaScript и C#, в то время как Puppeteer поддерживает только JavaScript, хотя существует неофициальный порт для Python.
Playwright поддерживает три браузера: Chromium, Firefox или WebKit. А Puppeteer, в свою очередь, поддерживает только Chromium.
Playwright
Playwright - это библиотека для сквозного веб-тестирования и автоматизации. Хотя основная роль фреймворка заключается в тестировании веб-приложений, его можно использовать для веб-скрейпинга.
В чем преимущества Playwright?
Благодаря единому API библиотека позволяет вам использовать Chromium, Firefox или WebKit для тестирования. Кроме того, кроссплатформенный фреймворк быстро запускается в Windows, Linux и MacOS.
Playwright поддерживает Python, Golang, Java, JavaScript и C#.
Playwright работает быстрее, чем большинство фреймворков для тестирования, таких как Cypress.
Каковы недостатки Playwright?
В Playwright отсутствует поддержка Ruby и Java.
Вместо реальных устройств Playwright использует десктопные браузеры для эмуляции мобильных устройств.
Playwright параметры браузера
Параметры браузера и страничные методы управляют тестовой средой.
Headless: определяет, будет ли вам виден браузер во время тестирования. В качестве дефолтного значения установлено false. Вы можете изменить его на true, чтобы видеть браузер во время тестирования.
SlowMo: замедленное движение уменьшает скорость переключения между действиями на странице. Например, значение 500 означает задержку на 500 миллисекунд.
DevTools: Открывает Chrome Dev Tools при запуске целевой страницы. Обратите внимание, что эта опция работает только для Chromium.
await playwright.chromium.launch({ devtools: true })Playwright методы объекта страницы
Здесь представлены некоторые методы для управления страницей запуска.
Методы объекта | Значение |
| Посетите страницу в первый раз |
| Этот метод обновляет страницу |
| Этот метод предоставляет вам мини API для захвата элемента и манипулирования им с помощью JavaScript для DOM в среде Node.js. В качестве альтернативы вы можете использовать |
| Чтобы сделать скриншот страницы. |
| Он позволяет headless-браузеру ожидать действия в течение определенного времени, прежде чем выдать ошибку. |
| Этот метод позволяет указать клавишу, которую нужно нажать. |
| Он указывает странице отложить действие до тех пор, пока не будет загружен определенный селектор. |
| Класс локатора захватывает элементы, используя несколько комбинаций селекторов. |
| Этот метод позволяет вам указать тег, селектор которого вы хотите кликнуть. |
Веб-скрейпинг с помощью Playwright
В качестве небольшого учебного пособия, призванного помочь в обсуждении Playwright и Puppeteer, давайте воспользуемся Playwright чтобы соскрейпить названия товаров, цены и URL-адреса изображений с Vue Storefront и сохраним результаты в CSV-файл.
Начните с импорта модуля Playwright, а также модуля файловой системы (fs) для сохранения данных, которые вы соскрейпили в CSV-файл.
import playwright from 'playwright' // web scraping
import fs from 'fs' // saving data to CSVНе забудьте указать тип модуля в файле package.json, иначе синтаксис import не будет работать.

Поскольку Playwright выполняется в асинхронной среде, а синтаксис async-await работает только в асинхронной функции, вы можете создать асинхронную функцию main и прописать в ней скрейпер.
const main = async () => {
// write some code
}
main()Следующим шагом будет запуск браузера и создание новой страницы - давайте запустим Chromium в режиме headed.
const browser = await playwright.chromium.launch({ headless: false })Вы открыли браузер, поздравляем, теперь мы уже на полпути к цели. Создайте объект страницы с помощью метода newPage() API браузера.
const page = await browser.newPage()Чтобы получить подробную информацию о товаре из Vue Storefront, давайте посетим страницу категории "Кухня" (kitchen) и отсортируем элементы по "Самым новым" (Newest).
await page.goto('https://demo.vuestorefront.io/c/kitchen?sort=NEWEST')В качестве альтернативы вы можете автоматизировать работу скрейпера, чтобы он определял расположение и кликал по элементам каждый раз, пока не попадет на целевую страницу.

Давайте создадим CSV-файл и напишем его заголовки, чтобы соскрейпить название, цену и URL-адреса изображений.
fs.writeFileSync('products.csv', 'title,price,imageUrl\n')Вы можете найти элемент div, содержащий товары, с помощью селектора классов CSS и сохранить полученный массив элементов в переменной products (товары).
const products = await page.$$('.products__grid > .sf-product-card.products__product-card')Используя цикл for-of, извлеките заголовок, цену и URL изображения из каждого дочернего элемента (продукта), как показано ниже:
for (const product of products) {
let title, price, imageUrl
// extracting the target portions into title, price and image urls, respectively
title = await page.evaluate(e => e.querySelector('.sf-product-card__title').textContent.trim(), product)
price = await page.evaluate(e => e.querySelector('.sf-price__regular').textContent.trim(), product)
imageUrl = await page.evaluate(e => e.querySelector('.sf-image.sf-image-loaded').src, product)
// for every loop, append the extracted data into the CSV file
fs.appendFile('products.csv', `${title},${price},${imageUrl}\n`, e => { if (e) console.log(e) })
}Закройте браузер и выполните файл скрипта.
await browser.close()И вот! Получилась идеально соскрейпенная с помощью Playwright веб-страница.

На случай, если вы запутаетесь, вот как выглядит полный код:
// in index.js
// Import the modules: playwright (web scraping) and fs (saving data to CSV)
import playwright from 'playwright'
import fs from 'fs'
// create asynchronous main function
const main = async () => {
// launch a visible chromium browser
const browser = await playwright.chromium.launch({ headless: false })
// create a new page object
const page = await browser.newPage()
// visit the target page
await page.goto('https://demo.vuestorefront.io/c/kitchen?sort=NEWEST')
// create a CSV file, in readiness to save the data we are about to scrape
fs.writeFileSync('products.csv', 'title,price,imageUrl\n')
// download an array of divs containing the target data
const products = await page.$$('.products__grid > .sf-product-card.products__product-card')
// loop through the array,
for (const product of products) {
let title, price, imageUrl
// dissecting the target portions into title, price and image urls, respectively
title = await page.evaluate(e => e.querySelector('.sf-product-card__title').textContent.trim(), product)
price = await page.evaluate(e => e.querySelector('.sf-price__regular').textContent.trim(), product)
imageUrl = await page.evaluate(e => e.querySelector('.sf-image.sf-image-loaded').src, product)
// for every loop, append the dissected data into the already created CSV file
fs.appendFile('products.csv', `${title},${price},${imageUrl}\n`, e => { if (e) console.log(e) })
}
// Close the (running headless) browser when the mission is accomplished
await browser.close()
}
// don't forget to run the main() function
main()Puppeteer
Puppeteer - это библиотека автоматизации для JavaScript (Node.js), и, в отличие от Playwright, Puppeteer загружает и использует Chromium по умолчанию. Она больше ориентирована на Chrome DevTools, что делает ее одной из лучших библиотек для веб-скрейпинга.
В чем преимущества Puppeteer?
Puppeteer упрощает начало работы по автоматизации браузера. Она управляет Chrome с помощью нестандартного протокола DevTools.
Каковы недостатки Puppeteer?
Puppeteer поддерживает только JavaScript (Node.js).
Хотя ведется разработка поддержки Firefox, в настоящее время Puppeteer поддерживает только Chromium.
Опции браузера в Puppeteer
Большинство опций браузера из Playwright, такие как headless, slowMo и devtools, работают и в Puppeteer.
await puppeteer.launch({ headless: false, slowMo: 500, devtools: true })Методы объекта страницы в Puppeteer
Большинство методов объекта страницы Playwright работают и в Puppeteer. Вот некоторые из них.
Методы объекта | Значение |
| Посетите страницу в первый раз |
| Перейти вперед |
| Вернуться на предыдущую страницу |
| Этот метод обновляет страницу |
| Этот метод предоставляет вам мини API для захвата элемента и манипулирования им с помощью JavaScript для DOM в среде Node.js. В качестве альтернативы можно использовать |
| Чтобы сделать скриншот страницы. |
| Позволяет headless-браузеру ожидать действия в течение заданного времени, прежде чем выдать ошибку. |
| Этот метод позволяет указать клавишу для нажатия. |
| Указывает странице отложить действие до тех пор, пока не будет загружен определенный селектор. |
| Для задержки последующих действий. |
| Класс локатора захватывает элементы, используя несколько комбинаций селекторов. |
| Этот метод позволяет вам указать тег, селектор которого вы хотите кликнуть. |
| Для выбора опции в элементе select. |
Веб-скрейпинг с помощью Puppeteer
Чтобы соскрейпить веб-страницу с помощью Puppeteer, импортируйте модуль Puppeteer для веб-скрейпинга и модуль fs для сохранения соскрейпенных данных в CSV-файл.
import puppeteer from 'puppeteer' // web scraping
import fs from 'fs' // saving scraped data Создайте асинхронную функцию для запуска headless-браузера.
const main = async () => {
// write some code
}
main()Теперь запустите headless-браузер и создайте новую страницу.
const browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()Используя метод goto(), посетите целевую страницу, прежде чем начать скрейпинг данных.
await page.goto('https://demo.vuestorefront.io/c/kitchen?sort=NEWEST')Затем создайте CSV-файл для хранения соскрейпенных данных.
fs.writeFileSync('products.csv', 'title,price,imageUrl\n')Найдите и просмотрите данные с веб-страницы
const products = await page.$$('.products__grid > .sf-product-card.products__product-card')Используя цикл for-of, извлеките название, цену и URL изображения товаров перед добавлением данных в CSV-файл.
for (const product of products) {
let title, price, imageUrl
// extracting the target portions into title, price and image urls, respectively
title = await page.evaluate( e => e.querySelector('.sf-product-card__title').textContent.trim(), product)
price = await page.evaluate( e => e.querySelector('.sf-price__regular').textContent.trim(), product)
imageUrl = await page.evaluate( e => e.querySelector('.sf-image.sf-image-loaded').src, product)
// for every loop, append the extracted data into the CSV file
fs.appendFile('products.csv', `${title},${price},${imageUrl}\n`, e => { if (e) console.log(e) })
}Наконец, закройте браузер и запустите скрипт.
await browser.close()Поздравляем, вы только что соскрейпили веб-страницу с помощью Puppeteer.
