为何$eval无法使用预定义变量?evaluate中console.log不显示如何解决?
Puppeteer常见问题解决
问题1:$eval设置输入框时变量提示未定义
原因
page.$eval的回调函数运行在浏览器页面上下文中,Node.js环境里定义的user、pass变量和浏览器上下文完全隔离,没有共享作用域,直接在回调里引用会触发未定义错误。
解决方法
把Node端的变量作为额外参数传递给$eval,让回调函数可以接收并使用这些变量:
// 正确写法:将user、pass作为第三个参数传入回调 await page.$eval('input[type="email"]', (el, user) => el.value = user, user); await page.$eval('input[type="password"]', (el, pass) => el.value = pass, pass);
问题2:evaluate内的console.log无法在Node终端显示
原因
page.evaluate的代码运行在浏览器环境中,这里的console.log会输出到浏览器开发者工具的控制台,和Node.js终端属于两个独立的输出环境,所以Node终端看不到浏览器里的日志。
解决方法
方法1:监听页面console事件,转发到Node终端
在创建页面后添加事件监听,把浏览器的console输出同步到Node终端:
const page = await browser.newPage(); // 添加监听,将浏览器日志转发到Node终端 page.on('console', msg => { console.log(`浏览器日志: ${msg.text()}`); }); // 之后evaluate里的console.log就会在Node终端显示 const dataTabla1Temp = await page.evaluate(()=>{ console.log("hi"); })
方法2:从evaluate返回数据,在Node端打印
如果只是需要传递信息,也可以直接从evaluate返回内容,在Node端处理打印:
const dataTabla1Temp = await page.evaluate(()=>{ const logMsg = "hi"; console.log(logMsg); // 浏览器控制台仍会输出 return logMsg; // 将内容返回给Node端 }); console.log(`Node终端输出: ${dataTabla1Temp}`); // Node终端打印内容
修复后的完整代码示例
const user= "user"; const pass = "password"; const page = await browser.newPage(); // 监听浏览器console,转发到Node终端 page.on('console', msg => { console.log(`浏览器日志: ${msg.text()}`); }); await page.goto("xxxxx", {waitUntil: "domcontentloaded"}).catch(err => console.log("error loading url", err)); // 传递变量到$eval回调 await page.$eval('input[type="email"]', (el, user) => el.value = user, user); await page.$eval('input[type="password"]', (el, pass) => el.value = pass, pass); await page.click("#_submit"); const dataTabla1Temp = await page.evaluate(()=>{ console.log("hi"); })
内容的提问来源于stack exchange,提问作者yavgz
相关产品推荐
相关产品推荐

