Передача переменной в функцию evaluate() в Puppeteer

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы внедрить переменную в page.evaluate при работе с Puppeteer, нужно передать её в качестве второго аргумента функции. Таким образом, вы сможете перенести значение из Node.js среды в контекст браузера:

JS
Скопировать код
const data = 'пример';
await page.evaluate((injectedData) => {
  // Теперь значение 'injectedData' доступно в браузере, проверим это
  console.log(injectedData);  // выводит: 'пример'
}, data);  // передаем 'пример', как обозначено в начале
Кинга Идем в IT: пошаговый план для смены профессии

Работа с несколькими переменными

Если требуется передать в функцию несколько переменных, просто включите их в список аргументов как дополнительные элементы:

JS
Скопировать код
const name = 'Алиса';
const age = 30;
await page.evaluate((userName, userAge) => {
  // Теперь значения 'userName' и 'userAge' доступны внутри функции — вот и вся магия Puppeteer!
}, name, age);

Обработка сложных типов данных

При передаче функций или несериализуемых объектов применяются JSHandles или сериализация:

JS
Скопировать код
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!"
});

Также можно сериализовать функцию, проявляя профессионализм:

JS
Скопировать код
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;:

JS
Скопировать код
// Готовы принять вызов, Нео?
await page.evaluate(() => {
  debugger;  // вызывает точку останова в коде, выполняющемся в браузере
});

Не забывайте включить { devtools: true } при запуске Puppeteer, чтобы избежать шрёдингеровского эффекта.

Вывод в консоль и безголовый режим

Обратите внимание, что console.log() внутри page.evaluate() работает не так, как вы привыкли — никакого вывода в консоль Node.js не произойдет. В безголовом режиме следите за выводом через событие page.on('console'):

JS
Скопировать код
page.on('console', msg => console.log('PAGE LOG:', msg.text()));

Сферы видимости, сериализация и вы

Сериализация может оказаться засадой, если ваша переменная содержит функции или символьные ключи, которые игнорируются в формате JSON. На благо, для таких ситуаций существуют сериализация кода и JSHandles.

Визуализация

...

Кейс-стади: За пределами известного

Хотите попробовать в деле деструктуризацию объектов, реализовать глобальные функции или опробовать работу в различных контекстах браузера?

JS
Скопировать код
// Попробуйте деструктурирование объекта в действии
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 не может обрабатывать их непосредственно.

Полезные материалы

...