克隆和nightmarejs

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

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

“抓取结束”也不会被logging。

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

日志

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

这不会做你期望的事情,并可能永远不会返回并导致超时错误。 你没有传入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 。 我不认为你把之前设置的datavariables,这应该总是输出undefined ,我想。 小心你的closures。

第三,也许最重要的是:

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

由于nightmare只定义了一次,你结束了唯一的例子。 它不会被重新创build,如果您尝试在循环的第二次迭代中对已结束的实例执行操作,将无法正常工作。 将.end()移出并移动到脚本的末尾,或者为每个迭代创build一个新的Nightmare实例。