尝试使用nightmarejs将捕获的数据保存到对象,这给了我错误

时间:2016-07-21 16:42:28

标签: javascript node.js nightmare

我想将这些数据保存到json文件中,但首先我要将标题,发布日期,评级和评论保存到movieData对象,但它给出了错误: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);
  });

1 个答案:

答案 0 :(得分:0)

您的问题属于范围之一。 第二个评估语句中的movieData不起作用,因为与第一个movieData函数中的原始evaluate对象文字相比,它位于不同的范围内。 要通过范围,您需要进行如下更改。

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()到{{ 1}}。