web-dev-qa-db-fra.com

Marionnettiste: variable de passage dans .evaluate ()

J'essaie de passer une variable dans une fonction page.evaluate() dans Puppeteer , mais lorsque j'utilise l'exemple très simplifié suivant, la variable evalVar n'est pas définie.

Je suis un nouveau venu dans Puppeteer et je ne trouve aucun exemple sur lequel construire. J'ai donc besoin d'aide pour passer cette variable à la fonction page.evaluate() afin de pouvoir l'utiliser à l'intérieur.

const puppeteer = require('puppeteer');

(async() => {

  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();

  const evalVar = 'WHUT??';

  try {

    await page.goto('https://www.google.com.au');
    await page.waitForSelector('#fbar');
    const links = await page.evaluate((evalVar) => {

      console.log('evalVar:', evalVar); // appears undefined

      const urls = [];
      hrefs = document.querySelectorAll('#fbar #fsl a');
      hrefs.forEach(function(el) {
        urls.Push(el.href);
      });
      return urls;
    })
    console.log('links:', links);

  } catch (err) {

    console.log('ERR:', err.message);

  } finally {

    // browser.close();

  }

})();
43
Cat Burston

Vous devez passer la variable comme argument à la pageFunction comme ceci:

const links = await page.evaluate((evalVar) => {

  console.log(evalVar); // should be defined now
  …

}, evalVar);

Les arguments peuvent également être sérialisés: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args .

78
flozia

Je vous encourage à rester sur ce style, car il est plus pratique et lisible .

let name = 'jack';
let age  = 33;
let location = 'Berlin/Germany';

await page.evaluate(({name, age, location}) => {

    console.log(name);
    console.log(age);
    console.log(location);

},{name, age, location});
23
Mehdi Raash

Variable simple:

Vous pouvez passer one variable à page.evaluate() en utilisant la syntaxe suivante:

await page.evaluate( example => { /* ... */ }, example );

Remarque: Vous n'avez pas besoin de placer la variable dans (), sauf si vous allez transmettre plusieurs variables.

Variables multiples:

Vous pouvez passer plusieurs variables à page.evaluate() en utilisant la syntaxe suivante:

await page.evaluate( ( example_1, example_2 ) => { /* ... */ }, example_1, example_2 );

Remarque: Il n'est pas nécessaire de placer vos variables dans {}.

10
Grant Miller

Il m'a fallu un bon bout de temps pour comprendre que console.log() dans evaluate() ne peut pas apparaître dans la console de nœud.

Réf.: https://github.com/GoogleChrome/puppeteer/issues/1944

tout ce qui est exécuté dans la fonction page.evaluate est fait dans le contexte de la page du navigateur. Le script est exécuté dans le navigateur, pas dans node.js. Par conséquent, si vous vous connectez, il apparaîtra dans la console des navigateurs, ce qui vous empêchera de voir si vous utilisez sans tête. Vous ne pouvez pas non plus définir de point d'arrêt de noeud dans la fonction.

J'espère que cela peut aider.

6
harrrrrrry

Pour passer une function, vous pouvez le faire de deux manières.

// 1. Define in evaluationContext
await page.evaluate(() => {
  window.yourFunc = function() {...};
});
const links = await page.evaluate(() => {
  const func = window.yourFunc;
  func();
});


// 2. Transform function to serializable. (Function can not be serialized)
const yourFunc = function() {...};
const obj = {
  func: yourFunc.toString()
};
const links = await page.evaluate((obj) => {
   const funStr = obj.func;
   const func = new Function(`return ${funStr}.apply(null, arguments)`)
   func();
}, obj);
0
wolf