Cron和nightmarejs

时间:2016-11-02 11:58:07

标签: javascript node.js cron nightmare

我无法用nightmarejs来管理我的cron。

函数get_data()的第一次迭代效果很好但在此之后cron重新启动并且函数不会再次被触发。

此外,“抓取已结束”永远不会被记录。

你知道我的代码有什么问题吗?

日志

1
cron
data fetched
2
cron
3
cron

-

var Nightmare = require('nightmare')
var nightmare = Nightmare({
  typeInterval: 300,
  show: true,
  executionTimeout: 120000,
  gotoTimeout: 120000
});
let data = ""

-

var get_data = function(){
  return new Promise(function(resolve, reject) {
    nightmare
    .goto('https://url.com')
    .type('[name=email]', '')
    .wait(1000)
    .type('[name=email]', 'myemail')
    .wait(1000)
    .type('[name=password]', '')
    .wait(1000)
    .type('[name=password]', 'mypassword')
    .click('[type=submit]')
    .wait(5000)
    .goto('https://url.com')
    .wait(25000)

    .evaluate(function (page, done) {

      return document.body.innerText
      done()
    })
    .end()
    .then(function (result) {
      data = result
    })
    .then(function(data){
      return fs.writeFile("./data.txt", data, function(err) {
        if(err) {
          console.log(err)
          reject(err)
        }
        resolve(data)
      });
    })
    .catch(function(error){
      reject(error)
    })
  })
}

-

var i = 0
var job = new CronJob('0 */20 * * * *', function() {
    ++i
    console.log(i)
    console.log("cron")
    get_data()
  }, function () {
    console.log("crawl ended")
  },
  true
);

job.start();

1 个答案:

答案 0 :(得分:1)

立即跳出来的一些事情。

.evaluate(function (page, done) {

      return document.body.innerText
      done()
    })

这不会做你期望它做的事情,并且可能永远不会返回并导致超时错误。您没有传递page的参数,这意味着done将是未定义的。将上述内容更改为:

.evaluate(function (done) {

      return document.body.innerText
      done()
    })

第二,这:

.then(function(data){
      return fs.writeFile("./data.txt", data, function(err) {
        if(err) {
          console.log(err)
          reject(err)
        }
        resolve(data)
      });
    })

...重新定义data。我不认为你在前一次推出了data变量集,我应该总是输出undefined,我想。小心你的封闭。

第三,也许最重要的是:

.evaluate(function (page, done) {

      return document.body.innerText
      done()
    })
    .end() // <== this might be a problem
    .then(function (result) {
      data = result
    })

由于nightmare仅定义一次,因此您将结束您拥有的唯一实例。如果您尝试在循环的第二次迭代中对结束的实例执行操作,则不会重新创建它,并且将无法正常工作。取出.end()并将其移到脚本的末尾,或者为每次迭代创建一个新的Nightmare实例。