Cron 和 nightmarejs

Cron and nightmarejs

我无法使用 nightmarejs 来 运行 我的 cron。

函数 get_data() 的第一次迭代运行良好,但之后 cron 重新启动并且函数不会再次被触发。

另外 "crawl ended" 从未被记录。

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

日志

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();

几件事马上就跳出来了。

.evaluate(function (page, done) {

      return document.body.innerText
      done()
    })

这不会执行您期望的操作,并且可能永远不会 return 并导致超时错误。您没有为 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 实例。