Передача переменной в функцию evaluate() в Puppeteer
Быстрый ответ
Чтобы внедрить переменную в page.evaluate
при работе с Puppeteer, нужно передать её в качестве второго аргумента функции. Таким образом, вы сможете перенести значение из Node.js среды в контекст браузера:
const data = 'пример';
await page.evaluate((injectedData) => {
// Теперь значение 'injectedData' доступно в браузере, проверим это
console.log(injectedData); // выводит: 'пример'
}, data); // передаем 'пример', как обозначено в начале
Работа с несколькими переменными
Если требуется передать в функцию несколько переменных, просто включите их в список аргументов как дополнительные элементы:
const name = 'Алиса';
const age = 30;
await page.evaluate((userName, userAge) => {
// Теперь значения 'userName' и 'userAge' доступны внутри функции — вот и вся магия Puppeteer!
}, name, age);
Обработка сложных типов данных
При передаче функций или несериализуемых объектов применяются JSHandles или сериализация:
await page.exposeFunction('myFunc', () => { console.log("All your base are belong to us!") });
await page.evaluate(async () => {
await window.myFunc(); // выводит: "All your base are belong to us!"
});
Также можно сериализовать функцию, проявляя профессионализм:
const complexFunction = function() { console.log("Can't touch this!") };
const stringifiedFunction = complexFunction.toString();
await page.evaluate(new Function(`return (${stringifiedFunction})();`)); // выводит: "Can't touch this!"
Подсказки для отладки
Чтобы отладить выполнение кода внутри page.evaluate
, применяйте оператор debugger;
:
// Готовы принять вызов, Нео?
await page.evaluate(() => {
debugger; // вызывает точку останова в коде, выполняющемся в браузере
});
Не забывайте включить { devtools: true }
при запуске Puppeteer, чтобы избежать шрёдингеровского эффекта.
Вывод в консоль и безголовый режим
Обратите внимание, что console.log()
внутри page.evaluate()
работает не так, как вы привыкли — никакого вывода в консоль Node.js не произойдет. В безголовом режиме следите за выводом через событие page.on('console')
:
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
Сферы видимости, сериализация и вы
Сериализация может оказаться засадой, если ваша переменная содержит функции или символьные ключи, которые игнорируются в формате JSON. На благо, для таких ситуаций существуют сериализация кода и JSHandles.
Визуализация
...
Кейс-стади: За пределами известного
Хотите попробовать в деле деструктуризацию объектов, реализовать глобальные функции или опробовать работу в различных контекстах браузера?
// Попробуйте деструктурирование объекта в действии
const user = { name: 'Алиса', age: 30 };
await page.evaluate(({ name, age }) => {
// 'name' и 'age' доступны как отдельные переменные
}, user);
// Создаём глобальную функцию в контексте браузера:
await page.evaluate(() => {
window.myGlobalFunction = () => { console.log("Привет, мир!"); };
});
// Ваши достижения вызывают восхищение.
// Следующий пример поможет вам разобраться с работой в разных контекстах браузера:
// (Напоминаем, что прямое манипулирование DOM из Node.js не поддерживается.)
Ловушки и спасательные круги
Когда вы погружаетесь в написание скриптов, будьте всегда начеку, чтобы избежать следующих распространенных ошибок:
- Область видимости: Не забывайте, что вне
page.evaluate
объявленные переменные не видны внутри, если вы их явно не передали. - Сериализация: Возникают проблемы, если вашу переменную не удаётся сериализовать. В таком случае,
JSON.stringify
иJSHandles
придут на помощь. - Слушатели событий: События, создаваемые кодом в
page.evaluate
, остаются внутри этого же браузера. Node.js не может обрабатывать их непосредственно.
Полезные материалы
...