2013-09-28 4 views
0

'요청'과 'cheerio'를 사용하여 스크래퍼를 작성하려고합니다. 나는 100 개의 URL 배열을 가지고있다. 배열을 반복하고 각 URL에 '요청'을 사용하고 cheerio.load (body)를 수행합니다. 내가 3 이상을 증가 시키면 (즉, 테스트를 위해 < 3으로 변경) 스태커가 손상됩니다. var productNumber가 정의되지 않았으며 정의되지 않은 변수에서 split을 호출 할 수 없기 때문입니다. 웹 페이지가 응답하기 전에 for 루프가 계속 움직이고 있다고 생각합니다.이 질문은 nodeJS - Using a callback function with Cheerio이 동의하는 것 같습니다.cheerio node.js 콜백

내 문제는 정의되지 않은 변수가 없도록 웹 페이지가 '로드되었는지'또는 루프의 각 반복마다 구문 분석되는지를 이해할 수 없다는 것입니다. 다른 대답에 따르면 콜백이 필요하지 않지만 어떻게해야합니까? 출력의

for (var i = 0; i < productLinks.length; i++) { 
    productUrl = productLinks[i]; 
    request(productUrl, function(err, resp, body) { 
     if (err) 
      throw err; 
     $ = cheerio.load(body); 
     var imageUrl = $("#bigImage").attr('src'), 
      productNumber = $("#product").attr('class').split(/\s+/)[3].split("_")[1] 
     console.log(productNumber); 

    }); 
}; 

예 :

1461536 
1499543 

TypeError: Cannot call method 'split' of undefined 
+0

어떤 오류가 발생하고 있습니까? – dankohn

+0

질문에 추가, 정의되지 않은 분할을 호출 할 수 없습니다. 분할을 제거하고 imageUrl 및/또는 productNumber를 인쇄하면 일부 변수가 설정되지만 많이 정의되지 않아 웹 페이지가 응답하기 전에 루프가 계속 움직이고 있다고 생각하게됩니다. – brownie3003

답변

0

당신은 어떤 외부 사이트 (들)을 근근이 살아가고있다. HTML이 모두 똑같은 구조로되어 있는지 확신 할 수 없으므로이를 통과하는 방법에 대해 방어해야합니다.

var product = $('#product'); 
if (!product) return console.log('Cannot find a product element'); 
var productClass = product.attr('class'); 
if (!productClass) return console.log('Product element does not have a class defined'); 
var productNumber = productClass.split(/\s+/)[3].split("_")[1]; 
console.log(productNumber); 

이는 일이 잘못 갈 곳 디버깅, 아마도 당신은 쉽게 당신이 바라던대로 데이터 집합을 긁어 수없는 것을 나타 도움이됩니다.

1

반복 할 때마다 $ 변수를 새로 만들지 않으므로 요청이 완료되면 덮어 쓰게됩니다. 이것은 루프의 한 반복이 다른 반복에 의해 덮어 쓰이는 것처럼 $을 사용하는 정의되지 않은 동작으로 이어질 수 있습니다.

는 그래서 새로운 변수 생성하려고

: 또한

var $ = cheerio.load(body); 
^^^ this is the important part 

, 당신은 요청이 상황에서 (완료되기 전에 루프가 계속 가정에 정확을, 그것은 비동기 cheerio.load하지만 request 아니다)입니다. 이것이 비동기 I/O가 작동하는 방식입니다.

비동기 작업을 조정하려면 예를 들어 async 모듈을 사용할 수 있습니다. 이 경우 async.eachSeries이 유용 할 수 있습니다.