尝试使用 nightmarejs 将抓取的数据保存到 object,出现错误
Trying to save scraped data to an object with nightmarejs, gives me error
我想将该数据保存到 json 文件中,但首先我想将标题、发行日期、评级和评论保存到 movieData Object 但它给我错误:movieData 未定义.
var Nightmare = require('nightmare');
var fs = require('fs');
var nightmare = Nightmare({ show: true });
var movieData = {};
nightmare
.goto('http://www.imdb.com/')
.type('#navbar-query', 'ghostbusters')
.click('#navbar-submit-button')
.wait('#main')
.click('.findSection table .findResult a')
.wait('#wrapper')
.evaluate(function () {
movieData.title = document.querySelector('.title_wrapper h1').innerText;
movieData.releaseDate = document.querySelector('.subtext a[title*="dates" i]').innerText;
movieData.rating = document.querySelector('span[itemprop="ratingValue"]').innerText;
return movieData;
})
.then(function (data) {
console.log('Data = ' + JSON.stringify(data));
return nightmare
.click('.user-comments .see-more a:nth-child(3)')
.wait()
.select('select[name="filter"]', 'chrono')
.wait('#wrapper')
.evaluate(function () {
movieData.review = document.querySelector('#tn15content p').innerText;
return movieData;
})
.end()
.then(function (data) {
console.log('Review = ' + data.review);
})
})
.catch(function (error) {
console.error('Search failed:', error);
});
你的问题是范围之一。
movieData
在你的第二个评估语句中不起作用,因为它与第一个 evaluate
函数中的原始 movieData
对象文字相比处于不同的范围内。
要通过范围,您需要进行如下更改。
nightmare
.goto('http://www.imdb.com/')
.type('#navbar-query', 'ghostbusters')
.click('#navbar-submit-button')
.wait('#main')
.click('.findSection table .findResult a')
.wait('#wrapper')
// .evaluate(data1())
.evaluate(function () {
var movieData = {}
movieData.title = document.querySelector('.title_wrapper h1').innerText;
movieData.releaseDate = document.querySelector('.subtext a[title*="dates" i]').innerText;
movieData.rating = document.querySelector('span[itemprop="ratingValue"]').innerText;
return movieData;
})
.then(function (data) {
console.log('Data = ' + JSON.stringify(data));
return nightmare
.click('.user-comments .see-more a:nth-child(3)')
.wait()
.select('select[name="filter"]', 'chrono')
.wait('#wrapper')
.evaluate(function (b) {
b.review = document.querySelector('#tn15content p').innerText;
return b;
}, data)
.end()
.then(function (data) {
console.log('Review = ' + data.review);
console.log(data);
})
})
.catch(function (error) {
console.error('Search failed:', error);
});
这是可行的,因为您将对象 movieData
从第一个 then()
函数传递到第二个 then()
并将其传递到第三个范围,即 .evaluate()
通过b
。
我想将该数据保存到 json 文件中,但首先我想将标题、发行日期、评级和评论保存到 movieData Object 但它给我错误:movieData 未定义.
var Nightmare = require('nightmare');
var fs = require('fs');
var nightmare = Nightmare({ show: true });
var movieData = {};
nightmare
.goto('http://www.imdb.com/')
.type('#navbar-query', 'ghostbusters')
.click('#navbar-submit-button')
.wait('#main')
.click('.findSection table .findResult a')
.wait('#wrapper')
.evaluate(function () {
movieData.title = document.querySelector('.title_wrapper h1').innerText;
movieData.releaseDate = document.querySelector('.subtext a[title*="dates" i]').innerText;
movieData.rating = document.querySelector('span[itemprop="ratingValue"]').innerText;
return movieData;
})
.then(function (data) {
console.log('Data = ' + JSON.stringify(data));
return nightmare
.click('.user-comments .see-more a:nth-child(3)')
.wait()
.select('select[name="filter"]', 'chrono')
.wait('#wrapper')
.evaluate(function () {
movieData.review = document.querySelector('#tn15content p').innerText;
return movieData;
})
.end()
.then(function (data) {
console.log('Review = ' + data.review);
})
})
.catch(function (error) {
console.error('Search failed:', error);
});
你的问题是范围之一。
movieData
在你的第二个评估语句中不起作用,因为它与第一个 evaluate
函数中的原始 movieData
对象文字相比处于不同的范围内。
要通过范围,您需要进行如下更改。
nightmare
.goto('http://www.imdb.com/')
.type('#navbar-query', 'ghostbusters')
.click('#navbar-submit-button')
.wait('#main')
.click('.findSection table .findResult a')
.wait('#wrapper')
// .evaluate(data1())
.evaluate(function () {
var movieData = {}
movieData.title = document.querySelector('.title_wrapper h1').innerText;
movieData.releaseDate = document.querySelector('.subtext a[title*="dates" i]').innerText;
movieData.rating = document.querySelector('span[itemprop="ratingValue"]').innerText;
return movieData;
})
.then(function (data) {
console.log('Data = ' + JSON.stringify(data));
return nightmare
.click('.user-comments .see-more a:nth-child(3)')
.wait()
.select('select[name="filter"]', 'chrono')
.wait('#wrapper')
.evaluate(function (b) {
b.review = document.querySelector('#tn15content p').innerText;
return b;
}, data)
.end()
.then(function (data) {
console.log('Review = ' + data.review);
console.log(data);
})
})
.catch(function (error) {
console.error('Search failed:', error);
});
这是可行的,因为您将对象 movieData
从第一个 then()
函数传递到第二个 then()
并将其传递到第三个范围,即 .evaluate()
通过b
。