2016-04-14 6 views
1

この質問は、クローラーに関するnode.jsです。 start_urlは、URLをクロールして、URLに「プッシュ」するところに与えられます。 json-ファイル(output.json)。 現時点では、彼はstart_urlでリクエスト機能を実行し、収集したURLをoutput.jsonに保存します。私は何を行うことができますことは、再帰的関数呼び出しを行うことで、彼が最初に収集されたURLにstart_urlを置き換えることによって、保存されたURLを使用して、もう一度リンクを集めることをしたい...というように...iterate node.js request function

var fs = require('fs'); 
var request = require('request'); 
var cheerio = require('cheerio'); 

var start_url = ["http://stackoverflow.com/"] 

var req = function(url){ 
    request(url, function(error, response, html){ 
     var $ = cheerio.load(html); 

     var data = []; 

     $("a").each(function() { 
      var link = $(this); 
       var exurls = {exurl: new Array(link.attr("href"))} 

       data.push(exurls); 

       // Queue "exurls" for "start_url" and call the same function with the new URL (endless loop) 
       // save to "output.json" from time to time, so you can stop it anytime 
     }); 

     fs.writeFile("output.json", JSON.stringify(data, null, 4), function(err){ 
      if(err){ 
       console.log(err); 
      } else { 
       console.log("File successfully written!"); 
      } 
     }); 
    }); 
} 
for (var i = 0; i < start_url.length; i++){ 
    req(start_url[i]); 
} 
+0

を切り替え、私はあなたがしたいどのように理解していませんあなたが与えたコードを変更してください:それはあなたが尋ねるように既に働いているようです:発見されたすべてのリンクをキューに入れ、見つかったURLで関数( 'req()')を呼び出してください... – MarcoS

+0

@MarcoS:彼はstart_urlでリクエスト機能を1回だけ実行し、.json-Fileを作成して停止します。 –

+0

...あなたに尋ねると... – MarcoS

答えて

2

。以下の例では、動作するはずです:

var fs = require('fs'); 
 
var request = require('request'); 
 
var cheerio = require('cheerio'); 
 

 
var start_url = ["http://stackoverflow.com/"] 
 

 
var req = function(url){ 
 
    var count = 0; 
 
    
 
    request(url, function(error, response, html){ 
 
    var $ = cheerio.load(html); 
 

 
    $("a").each(function() { 
 
     var link = $(this); 
 
     var exurls = {exurl: new Array(link.attr("href"))} 
 

 
     start_url.push(exurls); 
 

 
     // Queue "exurls" for "start_url" and call the same function with the new URL (endless loop) 
 
     // save to "output.json" from time to time, so you can stop it anytime 
 
    }); 
 

 
    try { 
 
     fs.writeFileSync("output.json"); 
 
     console.log("File successfully written!"); 
 
    }catch(err){ 
 
     console.log(err); 
 
    } 
 
     
 
     ++count; 
 
     
 
     if(start_url.length > count) { 
 
     req(start_url[count]); 
 
     } 
 
    }); 
 
} 
 

 
return req(start_url[0]);

これに伴う問題は、あなたが完全にファイルごとに書き換えされていることです。これがしばらく続くと、あなたは記憶がなくなるでしょう。別のオプションは、

var fs = require('fs'); 
 
    var request = require('request'); 
 
    var cheerio = require('cheerio'); 
 

 
    var start_url = ["http://stackoverflow.com/"] 
 
    
 
    var wstream = fs.createWriteStream("output.json"); 
 

 
    var req = function(url){ 
 
     
 
     request(url, function(error, response, html){ 
 
     var $ = cheerio.load(html); 
 

 
     $("a").each(function() { 
 
      var link = $(this); 
 
      var exurls = {exurl: new Array(link.attr("href"))} 
 

 
      start_url.push(exurls); 
 

 
      // Queue "exurls" for "start_url" and call the same function with the new URL (endless loop) 
 
      // save to "output.json" from time to time, so you can stop it anytime 
 
      wstream.write('"'+ exurls + '",'); 
 
     }); 
 
      
 
     start_url.shift(); 
 
     if(start_url.length > 0) { 
 
      return req(start_url[0]); 
 
     } 
 
      
 
      wstream.end(); 
 
     }); 
 
    } 
 

 
    req(start_url[0]);

書き込みストリームを作成するために編集されていますので、戦闘メモリの問題の基本的なキューに



+0

ありがとう。私はあなたの2番目の解決策を好むが、それはエラーを表示...私は十分なメモリがありません... –

+0

それはあなたがまだ 'start_url'にプッシュしているためです。変数は完全にメモリに残っているので、メモリをかなり早く使い果たしてしまいます。キューを作成する必要があります。私は自分のレスポンスを編集して、最初の要素 'start_url'を取得して、各繰り返しの後に最初の要素を削除するようにしました。これは、各反復で複数のアイテムを追加する可能性が最も高いため、十分な時間が経過してもまだ動作しません。しかし試してみてください – aray12

+0

メモリの問題のように見えますが(少なくとも...)、cheerio cheerio \ lib \ parse.js:55と競合します。 output.jsonを読んで(その間に)、次のリンクを毎回取るのはなぜでしょうか。あなたの努力に感謝! –

関連する問題