在 Puppeteer 中使用 page.$eval() 时如何将变量放入浏览器上下文中?

How to put a variable inside a browser context when using page.$eval() in Puppeteer?

我正在尝试 运行 这样的代码:

    const login = "login";
    await page.$eval('#LoginForm_username', el => el.value = login);

它在表单字段中输入一个 login 值。

但是,我不断收到一个奇怪的错误:

Error: Evaluation failed: ReferenceError: login is not defined at puppeteer_evaluation_script:1:19 at ExecutionContext._evaluateInternal (/home/denis/WEB/nlu/node_modules/puppeteer/lib/ExecutionContext.js:122:13) at process._tickCallback (internal/process/next_tick.js:68:7) -- ASYNC -- at ExecutionContext. (/home/denis/WEB/nlu/node_modules/puppeteer/lib/helper.js:111:15) at ElementHandle.$eval (/home/denis/WEB/nlu/node_modules/puppeteer/lib/JSHandle.js:436:50) at process._tickCallback (internal/process/next_tick.js:68:7) -- ASYNC -- at ElementHandle. (/home/denis/WEB/nlu/node_modules/puppeteer/lib/helper.js:111:15) at DOMWorld.$eval (/home/denis/WEB/nlu/node_modules/puppeteer/lib/DOMWorld.js:156:21) at process._tickCallback (internal/process/next_tick.js:68:7) -- ASYNC -- at Frame. (/home/denis/WEB/nlu/node_modules/puppeteer/lib/helper.js:111:15) at Page.$eval (/home/denis/WEB/nlu/node_modules/puppeteer/lib/Page.js:347:29) at Page. (/home/denis/WEB/nlu/node_modules/puppeteer/lib/helper.js:112:23) at crawlForSchedule (/home/denis/WEB/nlu/crawler.js:99:16) at process._tickCallback (internal/process/next_tick.js:68:7)

据我了解,这意味着 login 变量超出了浏览器上下文或类似的内容。

我发现可以像这样使用 page.evaluate() 函数传递变量:

const links = await page.evaluate((evalVar) => {
  console.log(evalVar); // should be defined now
}, evalVar);

但是如何用 page.$eval() 函数做这样的事情呢?或者如何使用 page.evaluate() 函数实现所需的行为(表单字段输入)?

试试这个:

const login = "login";
await page.evaluate(login => {
    document.querySelector('#LoginForm_username').value = login;
}, login);

puppeteer's documentation之后,您可以看到我们可以在哪里插入参数。 我们可以看到参数是最后接收到的spreaded数组(...args)。

page.$eval(selector, pageFunction[, ...args])

所以我们传递 selector 然后是要评估的函数 pageFunction 最后是 pageFunction 的参数 ...args.

const login = "login" // Your variable
await page.$eval('#LoginForm_username', (el, loginValue) => { 
   el.value = loginValue
}, login);
  • el 是你的元素等同于 document.querySelector('#LoginForm_username')
  • loginValue 是您的 参数 ,它将接收变量 login(或任何您想要的)
  • 最后,您 login variable 传递给参数 loginValue

因为loginValue是一个参数,所以你可以传递任何你想要的东西。 示例:

await page.$eval('#LoginForm_username', (el, loginValue) => { 
 el.value = loginValue 
}, 'Denis');

类似问题的回答here