每当我尝试传递一个函数时,就像这样:
var myFunc = function() { console.log("lol"); };
await page.evaluate(func => {
func();
return true;
}, myFunc);
我明白了:
(node:13108) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Evaluation failed: TypeError: func is not a function
at func (<anonymous>:9:9)
(node:13108) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
为什么?怎么做正确?
谢谢!
€:让我澄清一下:我这样做是因为我想首先找到一些DOM元素并在该函数中使用它们,更像是这样(简化):
var myFunc = function(element) { element.innerHTML = "baz" };
await page.evaluate(func => {
var foo = document.querySelector('.bar');
func(foo);
return true;
}, myFunc);
解决方法:
在木偶操纵者issue中已经讨论过类似的问题.
有几种方法可以解决您的问题.第一条规则是保持简单.
评估功能
这是最快的做事方式,你可以传递函数并执行它.
await page.evaluate(() => {
var myFunc = function(element) { element.innerHTML = "baz" };
var foo = document.querySelector('.bar');
myFunc(foo);
return true;
});
事先公开功能
您可以使用page.evaluate或page.addScriptTag预先公开该函数
// add it manually and expose to window
await page.evaluate(() => {
window.myFunc = function(element) { element.innerHTML = "baz" };
});
// add some scripts
await page.addScriptTag({path: "myFunc.js"});
// Now I can evaluate as many times as I want
await page.evaluate(() => {
var foo = document.querySelector('.bar');
myFunc(foo);
return true;
});
使用ElementHandle
页.$(选择)
您可以将元素句柄传递给.evaluate并根据需要进行更改.
const bodyHandle = await page.$('body');
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
页.$EVAL
您可以定位一个元素并根据需要进行更改.
const html = await page.$eval('.awesomeSelector', e => {
e.outerHTML = "whatever"
});
诀窍是read the docs并保持简单.