web-dev-qa-db-ja.com

操り人形師:.evaluate()で変数を渡す

Puppeteerpage.evaluate()関数に変数を渡そうとしていますが、次の非常に簡単な例を使用すると、変数evalVarは未定義です。

私はPuppeteerが初めてで、ビルドするサンプルが見つからないため、その変数をpage.evaluate()関数に渡して、内部で使用できるようにする必要があります。

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();

  }

})();
58
Cat Burston

次のように、変数をpageFunctionへの引数として渡す必要があります。

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

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

}, evalVar);

引数はシリアル化することもできます: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args

98
flozia

便利読みやすいなので、このスタイルに固執することをお勧めします。

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});
30
Mehdi Raash

単一変数:

次の構文を使用して、1つの変数page.evaluate() に渡すことができます。

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

注:複数の変数を渡す場合を除き、変数を()で囲む必要はありません。

複数の変数:

次の構文を使用して、複数の変数page.evaluate() に渡すことができます。

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

注:変数を{}で囲む必要はありません。

13
Grant Miller

functionを渡すには、2つの方法があります。

// 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);
2
wolf

console.log()evaluate()がノードコンソールに表示できないことを理解するのにかなり時間がかかりました。

参照: https://github.com/GoogleChrome/puppeteer/issues/1944

page.evaluate関数内で実行されるすべては、ブラウザーページのコンテキストで実行されます。スクリプトはnode.jsではなくブラウザで実行されているため、ログを記録するとブラウザコンソールに表示され、ヘッドレスで実行している場合は表示されません。関数内にノードブレークポイントを設定することもできません。

これが役立つことを願っています。

1
harrrrrrry