2016-01-23 68 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