Передача параметров в evaluate является важной частью
работы с Puppeteer, поскольку позволяет взаимодействовать с контекстом
браузера, передавая данные для выполнения JavaScript-кода в среде
страницы.
Метод evaluate позволяет выполнять JavaScript-код в
контексте страницы, то есть в браузере, где работает Puppeteer. Когда
возникает необходимость передать данные в этот контекст для дальнейшего
использования в вычислениях или манипуляциях с DOM, нужно правильно
организовать процесс передачи и обработки этих данных.
Сигнатура метода выглядит так:
page.evaluate(pageFunction, ...args)
pageFunction — это функция, которая будет выполнена в
контексте страницы.
args — это аргументы, которые передаются в
pageFunction. Эти параметры сериализуются и отправляются в
браузер.
Простейший случай передачи параметров — это передача строк, чисел или других базовых типов данных. Например:
await page.evaluate((msg) => { console.log(msg); }, &
Здесь строка ‘Привет из evaluate’ передаётся как аргумент в
функцию, выполняемую в контексте страницы, и выводится в консоль
браузера.
Передача объектов и массивов
Можно передавать более сложные структуры данных, такие как объекты и
массивы. Эти данные будут сериализованы перед отправкой и
восстанавливаться в том виде, в котором они были переданы.
Пример:
const user = { name: 'Иван', age: 30 };
await page.evaluate((user) => {
console.log(user.name); // Выводит 'Иван'
}, user);
В данном случае объект user передаётся в
evaluate и доступен для использования в функции на
странице. Это полезно, например, при необходимости взаимодействовать с
данными пользователя, которые могут быть в другом контексте, например,
при тестировании веб-приложений, требующих авторизации.
Ограничения передачи параметров
Важно помнить, что все передаваемые параметры должны быть
сериализуемыми. Это означает, что функции, классы или другие сложные
объекты, не поддерживающие сериализацию, не могут быть переданы
напрямую. Например, передача элементов DOM или методов вызова
window в evaluate не будет работать корректно.
Пример с некорректной передачей:
const el = document.querySelector('div');
await page.evaluate((el) => {
console.log(el.innerHTML); // Это вызовет ошибку
}, el);
Здесь элемент DOM не может быть передан напрямую, так как он существует
только в контексте браузера и не может быть сериализован для передачи в
Puppeteer.
Использование параметров с асинхронной логикой
Если необходимо выполнить асинхронные операции, такие как получение
данных из внешних источников, можно использовать промисы в функции,
передаваемой в evaluate. Однако следует помнить, что
evaluate не может напрямую вернуть промисы. Вместо этого
нужно использовать await внутри самой функции:
await page.evaluate(async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
});
Здесь асинхронный запрос выполняется в контексте браузера, а результаты
возвращаются в лог.
Использование значений из контекста браузера
В некоторых случаях для выполнения тестов или автоматизации нужно
передать данные, которые находятся непосредственно в контексте страницы.
Например, если необходимо получить результат сжатия данных с сервера или
прочитать состояния интерфейса. В таких ситуациях можно работать с
параметрами, доступными на самой странице, а затем передавать их в
функцию evaluate.
Пример:
const pageTitle = await page.evaluate(() => {
return document.title; // Возвращаем заголовок страницы
});
console.log(pageTitle); // Выведет заголовок текущей страницы
В этом примере значение document.title извлекается из
контекста страницы и передается в основной процесс Puppeteer.
Проблемы с большими данными
Передача большого объема данных в evaluate может вызвать
проблемы с производительностью или даже привести к ошибкам, если данные
слишком сложны для сериализации. В таких случаях рекомендуется
минимизировать количество данных или их структуру перед отправкой в
evaluate. Это особенно важно при работе с большим
количеством элементов DOM или массивами.
const largeData = new Array(10000).fill('some data');
await page.evaluate((data) => {
console.log(data.length); // Можно обработать даже большие массивы, но важно следить за их размером
}, largeData);
Если данные слишком большие или сложные для нормальной работы, имеет
смысл использовать промежуточные шаги, например, сохранение информации в
cookies или локальное хранилище и последующее чтение этих данных внутри
страницы.
Заключение
Понимание того, как передавать параметры в evaluate, —
ключевой момент при автоматизации работы с Puppeteer. Правильная
сериализация данных и использование ограничений контекста страницы
позволяют эффективно решать задачи тестирования и автоматизации
веб-приложений.