mik*_*ana 7 google-chrome node.js headless-browser puppeteer
我有一个非常简单的Puppeteer脚本,用于exposeFunction()
在无头Chrome中运行一些东西.
(async function(){
var log = console.log.bind(console),
puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
var functionToInject = function(){
return window.navigator.appName;
}
await page.exposeFunction('functionToInject', functionToInject);
var data = await page.evaluate(async function(){
console.log('woo I run inside a browser')
return await functionToInject();
});
console.log(data);
await browser.close();
})()
Run Code Online (Sandbox Code Playgroud)
这失败了:
ReferenceError: window is not defined
Run Code Online (Sandbox Code Playgroud)
其中指的是注入的功能.如何window
在无头Chrome内部进行访问?
我知道我可以做evaluate()
,但这不适用于我动态传递的函数:
(async function(){
var log = console.log.bind(console),
puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
var data = await page.evaluate(async function(){
console.log('woo I run inside a browser')
return window.navigator.appName;
});
console.log(data);
await browser.close();
})()
Run Code Online (Sandbox Code Playgroud)
evaluate
功能您可以通过动态脚本使用evaluate
。
(async function(){
var puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
var functionToInject = function(){
return window.navigator.appName;
}
var data = await page.evaluate(functionToInject); // <-- Just pass the function
console.log(data); // outputs: Netscape
await browser.close();
})()
Run Code Online (Sandbox Code Playgroud)
addScriptTag
和 readFileSync
您可以将函数保存到单独的文件中,并使用来使用该函数addScriptTag
。
await page.addScriptTag({path: 'my-script.js'});
Run Code Online (Sandbox Code Playgroud)
或evaluate
与readFileSync
。
await page.evaluate(fs.readFileSync(filePath, 'utf8'));
Run Code Online (Sandbox Code Playgroud)
或者,将参数化函数作为字符串传递给page.evaluate
。
await page.evaluate(new Function('foo', 'console.log(foo);'), {foo: 'bar'});
Run Code Online (Sandbox Code Playgroud)
您是否需要其他方法来解决这个问题?把它变成一个runnable
函数:D怎么样?
function runnable(fn) {
return new Function("arguments", `return ${fn.toString()}(arguments)`);
}
Run Code Online (Sandbox Code Playgroud)
以上将使用提供的参数创建一个新函数。我们可以传递我们想要的任何功能。
例如带有的以下函数window
以及参数,
function functionToInject() {
return window.location.href;
};
Run Code Online (Sandbox Code Playgroud)
也可以完美地履行承诺
function functionToInject() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(window.location.href);
}, 5000);
});
}
Run Code Online (Sandbox Code Playgroud)
加上论点
async function functionToInject(someargs) {
return someargs; // {bar: 'foo'}
};
Run Code Online (Sandbox Code Playgroud)
通过调用所需的功能evaluate
,
var data = await page.evaluate(runnable(functionToInject), {bar: "foo"});
console.log(data); // shows the location
Run Code Online (Sandbox Code Playgroud)
exposeFunction()
不是这项工作的正确工具。
page.exposeFunction(name,puppeteerFunction)
puppeteerFunction回调函数,将在Puppeteer的上下文中调用。
“在木偶的背景下”有点模糊,但请查看文档evaluate()
:
page.evaluateHandle(pageFunction,... args)
pageFunction 在页面上下文中要评估的函数
exposeFunction()
不会公开要在页面内运行的函数,而是公开了要在要从页面调用的节点中运行的函数。
我必须使用evaluate()
:
归档时间: |
|
查看次数: |
5036 次 |
最近记录: |