我无法用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();
答案 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实例。