Я пытаюсь передать переменную .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();
Я нашел решение здесь, но оно возвращает мне undefined
. Я также нашел это, в котором говорится об аналогичной вещи в PhantomJS, но еще не придумали работоспособный код.
Array.prototype.forEach
возвращаетundefined
. ИспользуйтеArray.prototype.find
. - person Noah Freitas   schedule 30.09.2017nightmare.evaluate
? То, что у вас есть, не похоже на обещание, и это единственное, чтоawait
может контролировать. По крайней мере, так, как вы ожидаете. - person Andrew   schedule 30.09.2017Array.prototype.find
, но код, который мне пришлось написать сразу после этого, страдает от той же проблемы, которуюfind
не решит. - person xendi   schedule 30.09.2017.evaluate()
на.then()
с тем же телом функции. - person Patrick Roberts   schedule 30.09.2017.then
, мне нужно, чтобы он работал в контексте веб-страницы. Вот для чего нужен.evaluate
. Я попробую это все же. - person xendi   schedule 30.09.2017