Playwright и Puppeteer в 2023 году: что выбрать

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Дебаты по поводу выбора между 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 методы объекта страницы 

Здесь представлены некоторые методы для управления страницей запуска.

Методы объекта

Значение

goto()

Посетите страницу в первый раз

reload()

Этот метод обновляет страницу

evaluate()

Этот метод предоставляет вам мини API для захвата элемента и манипулирования им с помощью JavaScript для DOM в среде Node.js.

В качестве альтернативы вы можете использовать $eval(), $$eval(), $() и $$().

screenshot()

Чтобы сделать скриншот страницы.

setDefaultTimeout()

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

keyboard.press()

Этот метод позволяет указать клавишу, которую нужно нажать.

waitForSelector()

Он указывает странице отложить действие до тех пор, пока не будет загружен определенный селектор.

locator()

Класс локатора захватывает элементы, используя несколько комбинаций селекторов.

click()

Этот метод позволяет вам указать тег, селектор которого вы хотите кликнуть.

Веб-скрейпинг с помощью 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. Вот некоторые из них.

Методы объекта

Значение

goto()

Посетите страницу в первый раз

goForward()

Перейти вперед

goBack()

Вернуться на предыдущую страницу

reload()

Этот метод обновляет страницу

evaluate() 

Этот метод предоставляет вам мини API для захвата элемента и манипулирования им с помощью JavaScript для DOM в среде Node.js. В качестве альтернативы можно использовать $eval(), $$eval(), $() и $$().

screenshot() 

Чтобы сделать скриншот страницы.

setDefaultTimeout() 
или 
setDefaultNavigationTimeout()

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

keyboard.press()

Этот метод позволяет указать клавишу для нажатия.

waitForSelector()

Указывает странице отложить действие до тех пор, пока не будет загружен определенный селектор.

waitFor()  

Для задержки последующих действий.

locator()

Класс локатора захватывает элементы, используя несколько комбинаций селекторов.

click()

Этот метод позволяет вам указать тег, селектор которого вы хотите кликнуть.

select()

Для выбора опции в элементе 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.

Источник: https://habr.com/ru/company/otus/blog/721740/


Интересные статьи

Интересные статьи

Судя по количеству анонсов в дайджесте — сезон мероприятий стартовал и уже в самом разгаре. В этой подборке — несколько курсов для тех, кто хочет развиваться или уже развивается в IT HR или рекрутмент...
Привет Хабр. Этой статьей мы начинаем цикл «Бытовой инфобез», в котором постараемся дать относительно простые ответы на вопросы личной информационной безопасности. По возможности постараемся не углубл...
С усложнением бизнес-задач в компаниях усложняются и требования к корпоративной системе аналитики. С одной стороны, она должна быть удобной, как для обычных пользователей, так и для техперсонала. ...
Нередко при работе с Bitrix24 REST API возникает необходимость быстро получить содержимое определенных полей всех элементов какого-то списка (например, лидов). Традиционн...
Добавим новую форму с кнопкой, нажав на которую будет открываться окно выбора файла. Читать далее