尝试使用 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