Answer the question
In order to leave comments, you need to log in
Nigtmare.js explain the behavior of the evaluate method?
Good day everyone. I am looking for support exclusively from those who have worked with nightmare and understand it in action.
The essence of the question is as follows, based on an example from the documentation
var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true })
nightmare
.goto('http://yahoo.com')
.type('form[action*="/search"] [name=p]', 'github nightmare')
.click('form[action*="/search"] [type=submit]')
.wait('#main')
.evaluate(function () {
return document.querySelector('#main .searchCenterMiddle li a').href
})
.end()
.then(function (result) {
console.log(result)
})
.catch(function (error) {
console.error('Search failed:', error);
});
Answer the question
In order to leave comments, you need to log in
const Nightmare = require('nightmare');
const nightmare = Nightmare({ show: true });
let results = [];
let res = nightmare
.goto('http://yahoo.com')
.type('form[action*="/search"] [name=p]', 'github nightmare')
.click('form[action*="/search"] [type=submit]')
.wait('#main')
.evaluate(function () {
return document.querySelector('#main .searchCenterMiddle li a').href;
})
.then(function(yahooResult) {
console.log('Yahoo result:', yahooResult);
results.push(yahooResult);
})
.then(function () {
return nightmare.goto('http://google.com')
.type('form[action*="/search"] [name=q]', 'github nightmare')
.click('form[action*="/search"] [type=submit]')
.wait('#main')
.evaluate(function () {
return document.querySelector('#search .g h3 a').href;
})
;
})
.then(function (googleResult) {
console.log('Google result:', googleResult);
results.push(googleResult);
})
.then(function () {
return nightmare.end();
})
.then(function() {
console.log('Full results:', results);
})
.catch(function (error) {
console.error('Search failed:', error);
})
;
nightmare
.goto(url1).click(selector1).evaluate(func1)
.goto(url2).click(selector1).evaluate(func1)
.end()
nightmare
.goto(url1).click(selector1).evaluate(func1)
.goto(url2).click(selector1).evaluate(func1)
.end()
.catch(errorHandler)
promise1 = Promise.resolve('Promise 1')
.then(function(){ var str = 'Promise 1-1'; console.log(str); return str;})
.then(function(){ var str = 'Promise 1-2'; console.log(str); return str;})
.then(function(){ var str = 'Promise 1-3'; console.log(str); return str;})
.then(function(){
return Promise.resolve('Promise 2')
.then(function(){ var str = 'Promise 2-1'; console.log(str); return str;})
.then(function(){ var str = 'Promise 2-2'; console.log(str); return str;})
.then(function(){ var str = 'Promise 2-3'; console.log(str); return str;})
.then(function(){
return Promise.resolve('Promise 3')
.then(function(){ var str = 'Promise 3-1'; console.log(str); return str;})
.then(function(){ var str = 'Promise 3-2'; console.log(str); return str;})
.then(function(){ var str = 'Promise 3-3'; console.log(str); return str;})
;
})
;
})
;
promise1
.then(function(res) {console.log('Result value:', res );})
;
Promise 1-1
Promise 1-2
Promise 1-3
Promise 2-1
Promise 2-2
Promise 2-3
Promise 3-1
Promise 3-2
Promise 3-3
Result value: Promise 3-3
Therefore, when receiving data sequentially, the code should be of the following structure:Example code when calling the `.evaluate()` method multiple times
nightmare.goto(url1).click(selector1).evaluate(func1).then(saveHandler1) .then( return nightmare.goto(url2).click(selector2).evaluate(func2).then(saveHandler2) ) .then( return nightmare.goto(url3).click(selector3).evaluate(func3).then(saveHandler3) ) .then( return nightmare.end() ) .catch(errorHandler) ;
Loops can be implemented via the reduce() method, but at the moment I find it easiest to write using await/async functions.An example of using `.evaluate()` in a loop with async/await functions
var urls = ['http://example.com', 'http://example2.com', 'http://example3.com']; var results = [] async function collectTitles(urls){ for ( url of urls ) { results.push(await nightmare.goto(url).wait('body').title()) } await nightmare.end() console.dir(results) } collectTitles(urls)
You can't do that. The code passed to the `.evaluate()` method works in the browser environment, not the node server, so the only way to pass data from the browser code to the nodejs code is to return the value from the browser function using the return statement and use then this value inside `.than()` function as function argument:An example of passing a value from a browser to an executable script
var nodeArray = []; nightmare .goto(url) .evaluate(function(){ }) .then(function(){ var ret = []; /* do some work with ret */ return ret; }) //т.к. этот код выполняется в окружении браузера, то у него нет доступа к переменным объявkенным в окружении nodejs, в том числе и к nodeArray. Значение `ret` будет передано первым аргументом в последющей then()-ф-ции .then(function(browserRet){ nodeArray = nodeArray.concat(browserRet); }) // browserRet равен значению ret вычисленному в браузере, но переменная ret для окружения сервера не определена.
In order to understand what is happening in the script, I recommend that you enable the output of debug messages at startup as described in the documentation .
I also recommend that you read the code examples and comments to them in the rosshinkley/nightmare-examples repository__ _, 2016-06-24
@AMar4enkovar Nightmare = require('nightmare'); var nightmare = Nightmare({ show: true })ж var results = []; nightmare .goto('http://yahoo.com') .type('form[action*="/search"] [name=p]', 'github nightmare') .click('form[action*="/search"] [type=submit]') .wait('#main') .evaluate(function () { return document.querySelector('#main .searchCenterMiddle li a').href; }) .then(results.push.bind(results)) .goto('http://google.com') .type('form[action*="/search"] [name=p]', 'github nightmare') .click('form[action*="/search"] [type=submit]') .wait('#main') .evaluate(function () { return document.querySelector('#main .searchCenterMiddle li a').href; }) .then(results.push.bind(results)) .end() .then(function() { console.log(results); }) .catch(function (error) { console.error('Search failed:', error); });
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question