Wil*_*tin 5 loops asynchronous web-crawler node.js
我有一个HTTP Get请求,我想解析响应并将其保存到我的数据库.
如果我打电话抓(i)独立,我会得到很好的结果.但我必须从1到2000调用crawl().我得到了很好的结果,但有些响应似乎丢失了,有些响应是重复的.我不认为我理解如何调用数千个异步函数.我正在使用异步模块队列功能,但到目前为止,我仍然缺少一些数据,但仍然有一些重复.我在这做错了什么?谢谢你的帮助.
我的节点功能:
function getOptions(i) {
return {
host: 'magicseaweed.com',
path: '/syndicate/rss/index.php?id='+i+'&unit=uk',
method: 'GET'
}
};
function crawl(i){
var req = http.request(getOptions(i), function(res) {
res.on('data', function (body) {
parseLocation(body);
});
});
req.end();
}
function parseLocation(body){
parser.parseString(body, function(err, result) {
if(result && typeof result.rss != 'undefined') {
var locationTitle = result.rss.channel[0].title;
var locationString = result.rss.channel[0].item[0].link[0];
var location = new Location({
id: locationString.split('/')[2],
name: locationTitle
});
location.save();
}
});
}
N = 2 //# of simultaneous tasks
var q = async.queue(function (task, callback) {
crawl(task.url);
callback();
}, N);
q.drain = function() {
console.log('Crawling done.');
}
for(var i = 0; i < 100; i++){
q.push({url: 'http://magicseaweed.com/syndicate/rss/index.php?id='+i+'&unit=uk'});
}
Run Code Online (Sandbox Code Playgroud)
[编辑]很好,经过大量的测试后,似乎我正在抓取的服务无法处理如此多的快速请求.因为当我按顺序执行每个请求时,我可以获得所有好的响应.
有没有办法慢下来ASYNC队列方法?
Mus*_*afa 15
你应该看看这个伟大的模块async,它简化了像这样的异步任务.您可以使用队列,简单示例:
N = # of simultaneous tasks
var q = async.queue(function (task, callback) {
somehttprequestfunction(task.url, function(){
callback();
}
}, N);
q.drain = function() {
console.log('all items have been processed');
}
for(var i = 0; i < 2000; i++){
q.push({url:"http://somewebsite.com/"+i+"/feed/"});
}
Run Code Online (Sandbox Code Playgroud)
如果您只调用回调函数,它将有一个正在进行的操作窗口,任务室将可用于将来的任务.不同的是,您的代码现在可以立即打开2000个连接,显然失败率很高.将其限制在合理的值,5,10,20(取决于站点和连接)将导致更好的成功率.如果请求失败,您可以再次尝试,或将任务推送到另一个异步队列以进行另一个试验.关键是在队列函数中调用callback(),以便在完成后可以使用房间.
Aar*_*ang 10
var q = async.queue(function (task, callback) {
crawl(task.url);
callback();
}, N);
Run Code Online (Sandbox Code Playgroud)
你在开始上一个任务后立即执行下一个任务,这样,队列就没有意义了.您应该像这样修改您的代码:
// first, modify your 'crawl' function to take a callback argument, and call this callback after the job is done.
// then
var q = async.queue(function (task, next/* name this argument as 'next' is more meaningful */) {
crawl(task.url, function () {
// after this one is done, start next one.
next();
});
// or, more simple way, crawl(task.url, next);
}, N);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15448 次 |
| 最近记录: |