[javascript] Puppeteer : .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();

  }

})();



답변

다음 pageFunction과 같이 변수를 인수로 전달해야합니다 .

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

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

}, evalVar); // 1. pass variable as an argument

인수는 https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args에서 직렬화 할 수도 있습니다 .


답변

이 스타일은 더 편리 하고 읽기 쉬우 므로 계속 사용하는 것이 좋습니다 .

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


답변

단일 변수 :

다음 구문 을 사용하여 하나의 변수 를에 전달할 수 있습니다 page.evaluate().

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

참고 :() 여러 변수를 전달하지 않는 한 변수를으로 묶을 필요가 없습니다 .

여러 변수 :

다음 구문 을 사용하여에 여러 변수 를 전달할 수 있습니다 page.evaluate().

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

참고 : 변수를 포함 {}할 필요는 없습니다.


답변

그것은 것을 알아 내기 위해 나에게 꽤 걸렸다 console.log()에서 evaluate()노드 콘솔에 표시 할 수 없습니다.

참고 : https://github.com/GoogleChrome/puppeteer/issues/1944

page.evaluate 함수 내에서 실행되는 모든 것은 브라우저 페이지의 컨텍스트에서 수행됩니다. 스크립트는 node.js가 아닌 브라우저에서 실행되므로 로그하면 브라우저 콘솔에 표시되며 헤드리스를 실행하는 경우에는 표시되지 않습니다. 함수 내에 노드 중단 점을 설정할 수도 없습니다.

이것이 도움이되기를 바랍니다.


답변

패스 a function의 경우 두 가지 방법이 있습니다.

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


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

   const foo = aObj.foo; // bar, for object
   window.foo = foo;
   debugger;
}, obj, otherObj);

devtools: true테스트를 위해 시작 옵션에 추가 할 수 있습니다.


답변

타이프 스크립트에서 새로운 사람을 도울 수있는 타이프 스크립트 예제가 있습니다.

const hyperlinks: string [] = await page.evaluate((url: string, regex: RegExp, querySelect: string) => {
.........
}, url, regex, querySelect);


답변

페이지입니다. $$ 평가

//..
const page = await browser.newPage();
const hrefs = await page.$$eval('#fbar #fsl a', as => as.map(a => a.href));
console.log(hrefs);
//..

[ 단일 선택기의 경우 page. $ eval 참조 ]