我想用nodejs 的http.get爬一堆文件下来,但是这个网站做了限制每次只能同时下载2个文件,而nodejs是异步的,问题来了…例如:
var urlArr = [ /* 一堆文件的url */ ];
for(/* 遍历urlArr */ ) {
http.get(url, ...); // http.get 下载文件
}
怎样做到每次只爬2个文件,或者第一次爬2个文件,然后这两个文件某个爬完了,又自动去爬下一个,总之每次只能有2个下载的请求,因为多了的那些请求是没法下载文件。。
期待大家的解答~~ 灰常感谢~~
28 回复
var urlArr = […]; count =0; for(…){ while(count==2){ // 休息10分钟 } // 在callback 里面 count-=1; http.get(url,…); count +=1; }
不知道可以不?
你這是黑@jeffz 啊
給個不用jscex的例子, 一起爬5個文件
async. forEachLimit(urlArr, 5, function(url, _callback) {
request(url, _callback);
}, function(err) {
console.log('damn err');
});
/**
* 下载文件
*
* @param {array} urlArr 一堆文件的url
* @param {int} threadCount 线程总数
* @param {function} callback 下载完成后的回调函数
*/
var download = function (urlArr, callback) {
// 模拟的线程
var thread = function () {
var url = urlArr.shift(); // 从URL列表中取一个出来
if (typeof url !== 'string') {
return threadDone();
}
http.get(url, function () { // http.get 下载文件
// 处理下载回来的文件
// ...
thread();
});
};
var finishThread = 0; // 已完成的线程数
var threadDone = function () {
finishThread++;
if (finishThread >= threadCount) {
return callback();
}
};
for (var i = 0; i < threadCount; i++) {
thread();
}
};
var nodeio = require('node.io');
var options = {
timeout: 10,
//线程个数
max:2
};
var url = [
'http://www.google.com/search?q=hello',
'http://www.google.com/search?q=keyword',
'http://www.google.com/search?q=ok',
'http://www.google.com/search?q=xxxx',
'http://www.google.com/search?q=hi',
'http://www.google.com/search?q=url2'
]
exports.job = new nodeio.Job(options, {
input: url,
run: function (keyword) {
this.getHtml(url, function (err, $) {
var results = $('#resultStats').text.toLowerCase();
this.emit(keyword + ' has ' + results);
});
}
});
就跟很多人说了用async.forEachLimit
就行了,forEachLimit
里面用Jscex写逻辑。如果你真要用Jscex——虽然我不觉得Jscex是处理这些事情的,就在循环里用whenAny
吧,whenAny
就是等待任意一个完成。还有真的,看看文档吧,不要搞到最后文档是白写的……