克隆和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
。 我不认为你把之前设置的data
variables,这应该总是输出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实例。