如何使用Puppeteer动态注入函数进行评估?

mik*_*ana 4 javascript headless-browser google-chrome-headless puppeteer

我正在使用Puppeteer用于无头Chrome.我希望评估页面内部的一个函数,该函数使用在其他地方动态定义的其他函数的部分.

下面的代码是最小的示例/证明.实际上functionToInject()并且otherFunctionToInject()更复杂并且需要页面DOM.

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(someURL);       

var functionToInject = function(){
    return 1+1;
}

var otherFunctionToInject = function(input){
    return 6
}

var data = await page.evaluate(function(functionToInject, otherFunctionToInject){
    console.log('woo I run inside a browser')
    return functionToInject() + otherFunctionToInject();
});

return data
Run Code Online (Sandbox Code Playgroud)

当我运行代码时,我得到:

错误:评估失败:TypeError:functionToInject不是函数

我理解的是:functionToInject没有被传递到页面的JS上下文中.但是如何将其传递到页面的JS上下文中?

Eve*_*tss 13

您可以使用addScriptTag以下命令向页面上下文添加功

const browser = await puppeteer.launch();
const page = await browser.newPage();

function functionToInject (){
    return 1+1;
}

function otherFunctionToInject(input){
    return 6
}

await page.addScriptTag({ content: `${functionToInject} ${otherFunctionToInject}`});

var data = await page.evaluate(function(){
    console.log('woo I run inside a browser')
    return functionToInject() + otherFunctionToInject();
});

console.log(data);

await browser.close();
Run Code Online (Sandbox Code Playgroud)

此示例是使用字符串连接解决此问题的一种肮脏方法.更干净的是使用urlpathaddScriptTag方法中.


或使用exposeFunction(但现在函​​数包含在Promise中):

const browser = await puppeteer.launch();
const page = await browser.newPage();

var functionToInject = function(){
    return 1+1;
}

var otherFunctionToInject = function(input){
    return 6
}

await page.exposeFunction('functionToInject', functionToInject);
await page.exposeFunction('otherFunctionToInject', otherFunctionToInject);

var data = await page.evaluate(async function(){
    console.log('woo I run inside a browser')
    return await functionToInject() + await otherFunctionToInject();
});

console.log(data);

await browser.close();
Run Code Online (Sandbox Code Playgroud)

  • 很高兴知道使用第一个方法 (addScriptTag),该函数在浏览器中执行。使用第二种方法 (exposeFunction),该函数在 Node.js 中执行。如果您需要将 DOM 元素传递给函数,则第一种方法是正确的选择。 (3认同)