2017-10-07 17 views
0

이것은 노드 js로 작성된 웹 스크래핑 코드입니다.
큐에 충분한 URL이 있으면이 코드가 항상 동시 요청을 5 개까지 유지합니까?
콘솔에 달리 표시되는 이유는 무엇입니까?
제한된 동시 작업 nodejs

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

var concurrent_requests = 0; 
var queue = []; 
var baseUrl = "https://angularjs.org/"; 

function makeApiCall(url){ 
    if(url) { 
     queue.unshift(url); 
    } 
    if(concurrent_requests<5) { 
     var nextUrl = queue.pop(); 
     if(nextUrl) { 
      concurrent_requests++; 
      request(nextUrl, function (error, response, body) { 
       var invalidUrl; 
       concurrent_requests--; 
       if(body) { 
        var $ = cheerio.load(body); 
        var anchors = $("a"); 
        var data = ""; 
        for (var i = 0; i < anchors.length; i++) { 
         url = $(anchors[i]).attr("href"); 
         if(!url || url === "#" || url === "javascript:void(0)"){ 
          invalidUrl = true; 
         } 
         else{ 
          invalidUrl = false; 
         } 

         if (!invalidUrl) { 
          makeApiCall(url); 
          data += url + ", " + nextUrl + "\n"; 
         } 
        } 
        //console.log(data); 
        fs.appendFile('urls.csv',data, function (err) { 
         if (err) throw err; 
        }); 
       } 
       else{ 
        makeApiCall(); 
       } 
      }); 
     } 
    } 
    console.log(concurrent_requests); 

} 


makeApiCall(baseUrl); 
+1

같은 루프를 사용합니다. –

+0

조금 더 명확히 해 주시겠습니까? –

+0

대답을 확인하십시오 –

답변

1

Becoz, 당신은 if 문에 5 개 이상을 요구하지 않는 상태 조건을 가지고있다. 특정 재귀 호출 후 스택을 통해 갈 것 같은

경우 (concurrent_requests < 5) {

이 솔루션은 확장 성이 없습니다.

희망이 있습니다.

+0

조금 더 명확히 해 주시겠습니까? –

1

if 조건을 사용하여 개의 동시 요청 수가 5 개 미만인지 확인합니다. 그러나 그것은 if 성명서, 루프가 아님을 기억하십시오. 즉 한 번만 부름을 의미합니다.

makeApiCall 함수의 재귀 호출을 요청의 콜백으로하고 있습니다. 요청이 완료되면 요청의 콜백은 만 실행합니다.

위의 두 가지 사항을 염두에두고 if 조건에서 concurrent_requests<5을 호출하면 요청 방법이 호출되고 프로그램이 이상적이됩니다. 언젠가 요청 ID가 충족되면 요청의 콜백이 실행되고, 일부 논리 후에는 makeApiCall이 다시 호출됩니다. 따라서 모든 호출에서 요청을 한 번만 호출 한 다음 해당 요청이 해결 될 때까지 기다렸다가 다음 요청을 위해 프로그램 만 진행합니다.

동시 요청을하려면 다음 그것은 한 번에 하나 개의 요청이있을 것이다이

function makeApiCall(url){ 
    if(url) { 
     queue.unshift(url); 
    } 
    // Use a loop here 
    while(concurrent_requests<5) { 
     var nextUrl = queue.pop(); 
     if(nextUrl) { 
      concurrent_requests++; 
      request(nextUrl, function (error, response, body) { 
       var invalidUrl; 
       concurrent_requests--; 
       if(body) { 
         ... 
         if (!invalidUrl) { 
          makeApiCall(url); 
          data += url + ", " + nextUrl + "\n"; 
         } 
        } 
        ... 
       } 
       else{ 
        makeApiCall(); 
       } 
      }); 
     } 
     else{ 
      // Remember to break out of loop when queue is empty to avoid infinite loop. 
      break; 
     } 
    } 
    console.log(concurrent_requests); 

}