我正在尝试将变量传递给.evaluate
,因此我可以在网页范围内使用它们,但我无法让它工作。
await nightmare.evaluate(function() {
let links = document.querySelectorAll('div.fsl a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
})
.evaluate(function(result) {
for(var i = 0; i < result.length; i++) {
var matchResult = result[i].match(/.com\/(.*?)\?fref/);
if (matchResult) {
console.log(matchResult[1]);
}
}
});
为此,我得到Cannot read property 'match' of undefined
。然后我尝试了:
const evaluated = await nightmare.evaluate(function() {
let links = document.querySelectorAll('div.fsl a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
});
await nightmare.evaluate(function(evaluated) {
for(var i = 0; i < evaluated.length; i++) {
var matchResult = evaluated[i].match(/.com\/(.*?)\?fref/);
if (matchResult) {
console.log(matchResult[1]);
}
}
});
结果相同。然后我尝试了:
const evaluated = await nightmare.evaluate(function() {
let links = document.querySelectorAll('div.fsl a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
});
for(var i = 0; i < evaluated.length; i++){
var matchResult = evaluated[i].match(/.com\/(.*?)\?fref/);
if(matchResult) {
console.log(matchResult[1]);
await nightmare.evaluate(function(matchResult) {
return document.body.innerHTML += '<a href="https://www.example.com/'+matchResult[0]+'">'+matchResult[0]+'</a>';
});
await nightmare.click('a[href="https://www.example.com/'+matchResult[0]+'"]');
await nightmare.wait(5000);
}
}
await nightmare.end();
为此,执行循环的第一次迭代,并将matchResult[1]
记录到控制台。然后我得到Error: Evaluation timed out after 30000msec. Are you calling done() or resolving your promises?
。
我也试过这样的事情:
await nightmare.evaluate(function() {
let links = document.querySelectorAll('div.fsl a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}).then(function(users){
}).end();
哪个确实将返回值传递给.then()
但是如何将数组传递给下一个评估?现在这是我能想到的最后一件事,但不起作用:
await nightmare.evaluate(function() {
let links = document.querySelectorAll('div.fsl a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}).evaluate((users) => {
console.log(users);
}).end();
我找到了解决方案here,但它为我返回undefined
。我还发现this在PhantomJS中讨论了类似的事情,但还没有提出可行的代码。
答案 0 :(得分:1)
我找到了答案。似乎有一半的尝试可能正在发挥作用,我只是没有意识到这一点。在.evaluate()
的范围内,我们处于浏览器范围内(按预期),但我没有考虑到我无法从该范围登录到控制台。具体来说,我无法登录到我的控制台。如果我从该范围运行console.log
,它将登录到浏览器控制台。以下代码有效:
var foo = "stuff";
var bar = "stuff for the remote page";
var result = await nightmare.evaluate(function(bar2) {
// this function executes in the remote context
// it has access to the DOM, remote libraries, and args you pass in
console.log("bla "+bar2); // this will not output
// but not to outer-scope vars
return typeof foo + " " + bar2;
}, bar);
console.log(result); // this logs bar2!
我认为这解决了它。调试文档范围内发生的事情可能有点棘手,但肯定是可能的。