Puppeteer : .evaluate ()에서 변수 전달


128

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

  }

})();

답변:


188

다음 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에서 직렬화 할 수도 있습니다 .


3
안녕하세요, 여러 변수를 어떻게 전달합니까?
chitzui

4
또한 실제로 함수를 전달할 수 없습니다. var myFunction = function () {console.log ( "hello")}; await page.evaluate (func => func (), myFunction); 나에게 준다 : Evaluation failed: TypeError: func is not a function.. 왜?
chitzui

1
evalVar함수 인수 시그니처와 전달 된 인수 evaluate(코드 예제 끝)에 모두 입력 하는 것을 잊지 마십시오 .
Flimm

2
@chitzui : 함수를 pate.evaluate(). 당신은 아마 그것을 '노출'할 수 있습니다 page.exposeFunction. 자세한 내용은 stackoverflow.com/a/58040978을 참조하십시오 .
knod

이것이 가장 높은 upvotes를 가지고 있기 때문에 누구든지 이것으로 linting 오류를 경험 한 적이 있습니까? 특히 상위 범위에서 이미 선언 된 매개 변수를 사용합니다. 이 오류를 제외하고는 작동합니다.
Mix Master Mike

61

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

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

40

단일 변수 :

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

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

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

여러 변수 :

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

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

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


12

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

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

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

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


6

패스 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테스트를 위해 시작 옵션에 추가 할 수 있습니다.


그리고 나는 물건을 전달하고 싶습니까?
tramada

두 번째 경우에 인수를 어떻게 추가 하시겠습니까? 예를 들어 나는 yourFunc에 문자열 통과 추가 할
user3568719

yourFunc속성이 함수가 아닌 경우 개체로 바꿀 수 있습니다 . @tramada
늑대

당신은 그냥 간부 yourFunc @ user3568719 같은 FUNC (stringArg) 호출 할 수 있도록 FUNC은 youFunc 비슷합니다
늑대

객체를 창에 전달한 다음 액세스하는 방법을 보여 주시겠습니까?
wuno

2

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

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

puppeteer타이프 스크립트에서 어떻게 실행 합니까? 코드를 수정할 때마다 js로 트랜스 파일합니까?
avalanche1

예. 여기에서이 프로젝트를 볼 수 있습니다 -github.com/srinivasreddy/companies-list
Srinivas Reddy Thatiparthy

-1

페이지입니다. $$ 평가

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

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


질문에 대한 답은 무엇입니까? 테스트 컨텍스트에서 브라우저 컨텍스트로 전달하는 변수가 표시되지 않습니다.
Ambroise Rabier
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.