2016-01-23 58 views
0

我想要使用节点js构建一个web刮板。我有一个数组,它将具有动态大小。该数组由我需要访问的URL列表组成。我使用https://scotch.io/tutorials/scraping-the-web-with-node-js进行网页报废。我正在使用节点js的Request模块创建请求。我推荐这个http://www.sebastianseilund.com/nodejs-async-in-practice,我想async.forEach应该对我的场景有用,但我无法理解如何让API等待,直到所有的web scrapping结果都没有获得。我是新来的节点js。任何指导都会对我前进很有帮助。节点JS动态收集Ajax调用异步等待

好的。我正在添加一些我正在尝试的代码,但没有按照我想要的方式工作。 我希望Async方法的所有输出连接到某个数组作为对象列表,并将其作为JSON发送给客户端。

var express = require('express'); 
 
var fs = require('fs'); 
 
var request = require('request'); 
 
var cheerio = require('cheerio'); 
 
var app  = express(); 
 
var async = require('async'); 
 
app.get('/scrape', function(req, res){ 
 
\t 
 
    //URL list will be dynamic. 
 
\t var urlList = ['1','2','3']; 
 

 
//async for each 
 
async.forEach(urlList,function(url,callback){ 
 
    
 
    
 
    request({url: url, 
 
    headers:{ 
 
     'User-Agent': 'spider' 
 
    } 
 
    }, function(error, response, html){ 
 
     debugger; 
 
\t \t if(!error){ 
 
     debugger; 
 
\t \t \t var $ = cheerio.load(html); 
 
      
 
      
 
\t \t \t $('span').filter(function(){ 
 
       debugger; 
 
\t \t   var data = $(this); 
 
\t \t \t \t //console.log(data) 
 
\t \t   var someprocessedValue = data.attr('data'); 
 
\t \t   //release = data.children().last().children().text(); 
 
       callback(someprocessedValue); 
 
\t   }) 
 
\t   
 
\t \t } 
 
     
 
\t }); 
 
    
 
    
 
    
 
    
 
}, 
 
function(err){ 
 
    if(err) console.log(err); 
 
    res.send('Check your console!'); 
 
}); 
 

 
});

按照答案通过@Robrich我已经修改了代码,并得到了在那里工作的地方。如果有人想在以后使用它,我会发布代码以供参考。

app.get('/scrape', function(req, res) 
 
{ 
 
var urlList=['http://a.com','http://b.com']; 
 

 

 
async.map(urlList,scrapper,function(err,results){ 
 
    if(err){ 
 
     
 
    } 
 
    else 
 
    { 
 
     res.send('Check your console!'); 
 
    } 
 
}); 
 
} 
 
var scrapper = function(url,cb){ 
 
var data = new Object(); 
 
data.url = url; 
 
data.isError = false; 
 
    request({url: url, 
 
    headers:{ 
 
     'User-Agent': 'spider' 
 
    } 
 
    }, function(error, response, html){ 
 
     //debugger; 
 
\t \t if(!error){ 
 
     //debugger; 
 
\t \t \t var $ = cheerio.load(html); 
 
    
 
      //some logic 
 
\t \t \t 
 
\t   return cb(null,data); 
 
\t \t } 
 
     else{ 
 
      data.IsError=true; 
 
     return cb(error,data); 
 
     } 
 
     
 
\t }); 
 
}

我上面的代码可能有大括号的问题。但我按照我想要的方式工作。 谢谢!

+0

你试过async.parallel? (https://github.com/caolan/async#parallel) –

+0

其实我有一个集合,我需要从中动态创建异步。 – Mandy

回答

1

使用async.map代替async.forEach

+0

我有动态收藏。所以url的数量可能会有所不同每次。如何在运行中创建许多请求并等待请求完成,然后处理数据。最后使用你的建议返回一个新的阵列,其中包含所有执行结果。我无法理解。你能提供一些代码示例吗? – Mandy

+0

我知道它的工作。谢谢。 – Mandy