programing

변수를 평가 함수에 전달하려면 어떻게 해야 합니까?

nicescript 2022. 10. 30. 16:06
반응형

변수를 평가 함수에 전달하려면 어떻게 해야 합니까?

변수를 변환하려고 합니다.page.evaluate()Puppeteer에서 기능하지만 다음과 같은 매우 간단한 예를 사용하면 변수가evalVar정의되어 있지 않습니다.

Puppeteer는 처음이라 구축할 예를 찾을 수 없습니다.그래서 이 변수를 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

더 많은 인수를 전달하여 여러 변수를 전달할 수 있습니다.page.evaluate():

await page.evaluate((a, b c) => { console.log(a, b, c) }, a, b, c)

인수는 JSON으로 직렬화 가능해야 합니다.https://syslogr.dev/#?show=api-pageevalize pagefunction-s

이 스타일이 더 편리하고 읽기 쉬우니 그대로 쓰시길 권합니다.

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

단일 변수:

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

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

주의: 변수를 에 묶을 필요는 없습니다.()여러 변수를 전달하지 않는 한.

다중 변수:

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

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

주의: 변수 포함{}는 필요 없습니다.

내가 알아내는 데 꽤 오랜 시간이 걸렸다console.log()…에.evaluate()노드 콘솔에 표시할 수 없습니다.

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

page.display 함수 내에서 실행되는 모든 작업은 브라우저 페이지의 컨텍스트에서 수행됩니다.스크립트는 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);

위의 @wolf 답변과는 약간 다른 버전입니다.다른 컨텍스트 간에 코드를 훨씬 더 쉽게 재사용할 수 있습니다.

// util functions
export const pipe = (...fns) => initialVal => fns.reduce((acc, fn) => fn(acc), initialVal)
export const pluck = key => obj => obj[key] || null
export const map = fn => item => fn(item)
// these variables will be cast to string, look below at fn.toString()
const updatedAt = await page.evaluate(
  ([selector, util]) => {
    let { pipe, map, pluck } = util
    pipe = new Function(`return ${pipe}`)()
    map = new Function(`return ${map}`)()
    pluck = new Function(`return ${pluck}`)()

    return pipe(
      s => document.querySelector(s),
      pluck('textContent'),
      map(text => text.trim()),
      map(date => Date.parse(date)),
      map(timeStamp => Promise.resolve(timeStamp))
    )(selector)
  },
  [
    '#table-announcements tbody td:nth-child(2) .d-none',
    { pipe: pipe.toString(), map: map.toString(), pluck: pluck.toString() },
  ]
)

또한 파이프 내부의 기능은 이와 같은 것을 사용할 수 없습니다.

// incorrect, which is i don't know why
pipe(document.querySelector) 

// should be 
pipe(s => document.querySelector(s))

언급URL : https://stackoverflow.com/questions/46088351/how-can-i-pass-variable-into-an-evaluate-function

반응형