如何在Puppeteer的page.evaluate中传递变量与函数并解决请求报错
解决Puppeteer page.evaluate中无法访问Node.js变量和模块的问题
首先得搞明白为啥会出现这些报错:
ReferenceError: item is not defined:page.evaluate的回调函数是跑在浏览器的沙箱环境里,不是Node.js环境,所以Node端定义的item变量默认拿不到。ReferenceError: request is not defined:同理,request-promise是Node.js的专属模块,浏览器环境里根本不存在这个东西,不管怎么传都用不了。
正确思路:把请求逻辑移到Node.js环境里
既然浏览器环境用不了Node的模块,那咱们就把需要的浏览器数据(比如cookie)拿到Node端,然后在Node里用request-promise发送请求,别在page.evaluate里折腾这件事。
修改后的完整代码
async function start() { const item = { cin: "1234567" }; const request = require('request-promise').defaults({ followAllRedirects: true }); const puppeteer = require('puppeteer'); // 原代码漏了导入puppeteer,补上 async function loadPage() { const browser = await puppeteer.launch({ headless: false, executablePath: getChromiumExecPath() }); const page = (await browser.pages())[0]; await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'); await page.setViewport({ width: 1366, height: 768 }); // 1. 在Node端直接获取浏览器cookie,不用在evaluate里拿 const cookies = await page.cookies(); // 把cookie数组转成request需要的字符串格式(name=value; name2=value2) const cookieString = cookies.map(c => `${c.name}=${c.value}`).join('; '); // 2. 在Node端构造请求数据,动态使用item.cin const dataString = JSON.stringify({ tcin: item.cin }); // 原代码格式有误,这里修正 try { // 3. 在Node端发送请求,所有变量和模块都能正常访问 const res = await request.post({ headers: { "accept": "application/json", "accept-language": "en-US,en;q=0.9", "content-type": "application/json", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site", "x-application-name": "web", "cookie": cookieString }, referrer: "RANDOMURLHERE.com", body: dataString }); console.log(res); } catch (err) { console.error("请求出错:", err); } // 记得关闭浏览器,避免资源浪费 await browser.close(); } await loadPage(); // 原代码只写了函数名没调用,补上 } // 启动脚本 start().catch(err => console.error("启动出错:", err));
关键调整说明
- 环境边界:Node.js的模块(比如
request)和变量(比如item)全放在Node端处理,page.evaluate只用来做浏览器专属操作(比如页面跳转、DOM交互),别在里面碰Node模块。 - Cookie获取优化:用
page.cookies()直接在Node端拿浏览器cookie,比在evaluate里拿更简洁,还能直接格式化。 - 请求逻辑迁移:把POST请求从
page.evaluate移到Node端,这样动态变量和Node模块都能正常使用。 - 小问题修复:补上了原代码漏的
puppeteer导入、loadPage函数调用,还修正了dataString的格式错误。
关于硬编码“正常运行”的疑问
你提到硬编码item.tcin时脚本正常,大概率是因为变量问题解决后,request的报错被忽略了,或者那段代码根本没执行到。不管怎样,把请求逻辑移到Node端才是既能动态使用变量,又能正常调用request-promise的正确方式。
内容的提问来源于stack exchange,提问作者Prada
相关产品推荐
相关产品推荐

