我写了一个JavaScript对象,用标准的nodeJS http get方法擦除网站列表。
对我来说(对我来说是一个相对的nube)来处理所有的异步性并逐个排队请求是非常棘手的,所以我的机器没有发出数千(约2500)个请求曾经且明显崩溃。
所以这就是这个想法,以及它目前的运作方式:
var scraper = new WebsiteScraper();
mongooseDocs.forEach(function(doc){
var callback = function(outputFromWebPage, done){
var email = /*try find email*/
if(email){
doc.email = email;
doc.save(function(){
done();
})
}else{
done();
}
}
scraper.scrape(doc.website, callback);
})
function WebsiteScraper() {
this.active = true;
this.queue = [];
/** Add url to queue */
this.scrape = (function (url, callback) {
//console.log(url);
this.queue.push({url: url, callback: callback});
}).bind(this);
/** Execute the scrape */
this.execute = (function (url, done) {
if(url.indexOf("http") === -1) done();
var protocol = /https/.test(url) !== false ? https : http;
var req = protocol.get(url, (function (response) {
var output = '';
console.log("request made");
response.on('error', function (error) {
console.log(error);
done(false);
})
response.on('data', function (chunk) {
output += chunk;
})
response.on('end', (function () {
console.log("Request complete", url);
done(output);
}).bind(this))
}).bind(this));
req.setTimeout(20000, function () {
console.log("Timed out");
done(false);
});
req.on('error', function (e) {
console.log("Got error: " + e.message);
done(false);
})
req.end();
}).bind(this);
this.check = (function () {
if (this.queue[0] && this.queue[0].callback) {
this.execute(this.queue[0].url, (function (output) {
this.queue[0].callback(output, (function(){
this.queue.shift();
this.check();
}).bind(this));
console.log(this.queue.length, ' left in queue');
}).bind(this));
}
else {
setTimeout(this.check, 100);
}
}).bind(this);
this.check();
}
基本上:循环记录并将它们添加到列表中。只要队列中有url,网站scraper就会在内部遍历列表并执行请求。请求完成后,它执行用户定义的回调,只有在done()上执行下一个请求。
它工作正常,它找到了电子邮件,但如果它没有找到电子邮件地址,它会在下一条记录上移动时保存以前的输出电子邮件。我已经尝试了各种不同的绑定,并在完成后删除了电子邮件变量。
这已经困扰了我一个月了,请帮助:D