Javascript 使用不可序列化参数的Puppeter exposeFunction
我正在尝试使用第三方库来执行一些复杂的DOM解析:Javascript 使用不可序列化参数的Puppeter exposeFunction,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我正在尝试使用第三方库来执行一些复杂的DOM解析: /** * // Simplified for this example * module.exports.parse = (document) => {return document.title; } */ const { parse } = require('./parse.js'); 当我尝试暴露和评估木偶戏中的功能时: const browser = await puppeteer.launch(); const
/**
* // Simplified for this example
* module.exports.parse = (document) => {return document.title; }
*/
const { parse } = require('./parse.js');
当我尝试暴露和评估木偶戏中的功能时:
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://stackoverflow.com', { waitUntil: ['domcontentloaded'] });
await page.exposeFunction('parse', (document) => {
return parse(document);
});
await page.evaluate(() => {
return window.parse(window.document);
});
我得到一个错误:
评估失败:类型错误:在窗口的JSON.stringify()\n处将循环结构转换为JSON。(匿名函数)(木偶师评估脚本:13:22)\n在木偶师评估脚本:3:31处
在文档的示例中,它传递一个字符串(可以序列化)。是否有任何已知的方法可以评估node.js方法,这些方法将
窗口
或文档
作为其参数?下面解释的方法有点不同,因此请谨慎使用
我们可以将脚本带到浏览器,而不是将dom带到节点上下文。这是可能的与网页或浏览功能。同样这样,我们不需要序列化任何循环变量
这是最小的网页包配置
const path = require("path");
module.exports = {
entry: "./browser/src.js",
output: {
path: path.resolve("browser"),
filename: "dist.js",
libraryTarget: "global"
},
module: {
rules: [
{
test: /\.js$/,
use: "babel-loader"
}
]
}
};
我们将把浏览器脚本放在browser/src.js
文件夹中。然后当我们运行webpack
时,它将生成browser/dist.js
,我们可以将其注入浏览器
最后我可以用下面的一个来称呼它
await page.addScriptTag({path: "./browser/dist.js"});
await page.evaluate(fs.readFileSync("./browser/dist.js", 'utf8'));
只要我们不使用任何不可能捆绑的本机二进制文件,它就可以完美地工作
为简单起见,以下是其他文件
// browser/src.js
module.exports.parse = window => {
return window.location.href;
};
// index.js
const fs = require("fs");
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.evaluate(fs.readFileSync("./browser/dist.js", 'utf8'));
const data = await page.evaluate(() => {
return parse(window);
});
console.log({ data });
})();
// The result:
{ data: 'about:blank' }