[Node.js] SCRAPING을 위한 cheerio 모듈과 cheerio-httpcli 모듈[Node.js] SCRAPING을 위한 cheerio 모듈과 cheerio-httpcli 모듈

Posted at 2019. 5. 8. 16:59 | Posted in Node.js




발췌 : 자바스크립트와 Node.js를 이용한 웹 크롤링 테크닉





※ 스크래핑이란?


-. 웹의 세계에서 흔히 말하는 '스크래핑'은 웹 사이트에서 HTML 데이터를 수집하고, 특정 데이터를 추출, 가공하여 저장하는것을 말한다.

-. 단순히 웹 사이트에서 HTML 파일을 다운로드만 하는 것이 아니라 그 HTML 파일의 각 요소들을 분석하는 과정을 포함한다.





■ cheerio 모듈과 cheerio-httpcli 모듈에 관하여



-. cheerio 모듈을 사용하면 HTML / XML 데이터에 대해 jQuery(제이쿼리)처럼 임의의 요소를 획득하여 조작할 수 있다.

-. cheerio모 듈 이것을 이용한 것이 cheerio-httpchli 모듈이다.

-. cheerio-httpchli 모듈은 cheerio 모듈에서 웹 페이지 취득 기능을 추가한 것이다.



모듈

설 명

 cheerio

 · 웹 API나, cheerio-httpchli등으로이미 취득한 데이터에서 임의의 데이터를 가져오는 경우 사용

 cheerio-httpchli

 · 웹 페이지를 취득하는 경우 cheerio-httpchli 모듈을 사용










■ cheerio 모듈



#01. cheerio 모듈 설치

 $ npm install cheerio

 




#02. cheerio 모듈의 기본적인 사용방법


XML 데이터로부터 책의 제목 일람을 표시해 보자.



# 소스코드

 xml_title_list.js

// 모듈을 로드함

const cheerio = require( "cheerio" );


// 샘플 XML 데이터

var xml = "<books>";

xml += "<book><title>반쪽달이 떠오르는 하늘</title><author>하시모토 츠무구</author></book>";

xml += "<book><title>렌탈 마법사</title><author></author>산다 마코토</book>";

xml += "<book><title>강각의 레기오스</title><author>아마기 슈스케</author></book>";var

xml += "<books>";


// load( )를 메소드를 통해 XML 데이터를 읽음

var data = cheerio.loadxml );


// 책의 제목 일람을 표시

data( "title" ).each(function( key, val ) {

// each( ) 메서드의 인자로 주어지는 객체 변수 val 자체에는 text( ) 메서드가 존재하지 않는다.

// console.log( val.text() ); ← 에러발생

//

// 따라서 아래와 같이 data(val).text( ); 라고 기술해야 한다.


var bookTitledataval ).text();

console.log( bookTitle );

});




#03. 취득한 요소의 자식 요소 검사하기


지금부터는 여러 가지 프로그램을 작성하여 동작을 검증해 보자.



# XML 데이터

 light_novel.xml

<books>

<book id="ex001">

<title>이스캐리엇</title>

<author>산다 마코토</author>

<price value="5900"/>

<options>

<color>BLACK</color>

</options>

</book>

<book id="ex002">

<title>문학소녀</title>

<author>노무라 미즈키</author>

<price value="6800"/>

<options>

<color>GREEN</color>

</options>

</book>

<book id="nt001">

<title>사신의 발라드</title>

<author>하세가와 케이스케</author>

<price value="6000"/>

<options>

<color>WHITE</color>

</options>

</book>

<book id="nt002">

<title>스즈미야 하루히</title>

<author>타니가와 나가루</author>

<price value="7000"/>

<options>

<color>BLUE</color>

</options>

</book>

<book id="nt003">

<title>작안의 샤나</title>

<author>타카하시 야시치로</author>

<price value="7000"/>

<options>

<color>RED</color>

</options>

</book>

<book id="j001">

<title>제로의 사역마</title>

<author>야마구치 노보루</author>

<price value="6800"/>

<options>

<color>PINK</color>

</options>

</book>

<book id="j002">

<title>소드 아트 온라인</title>

<author>카와하라 레지</author>

<price value="7000"/>

<options>

<color>AZURE</color>

</options>

</book>

</books>





# 소스코드

 show_books_title.js

// 모듈을 로드함

const cheerio = require( "cheerio" );

const fs = require( "fs" );


// 샘플 XML 데이터를 cheerio로 읽어들임

var xml  = fs.readFileSync( "light_novel.xml", "utf-8" );


// load( )를 메소드를 통해 XML 데이터를 읽음

var data = cheerio.loadxml );


// 책의 정보를 표시

// children( ) 메서드를 사용하여 <book> 요소의 자식 요소를 다루고 있다.

data( "book" ).each(function( key, val ) {

// <book> 태그 자식요소로부터 값을 취득

var bookTitledataval ).children( "title" ).text( );

var bookAuthordataval ).children( "author" ).text( );

console.log( bookTitle + " - " + bookAuthor );

});




#04. 속성값 가져오기


# 소스코드

 show_books_price.js

// 모듈을 로드함

const cheerio = require( "cheerio" );

const fs = require( "fs" );


// 샘플 XML 데이터를 cheerio로 읽어들임

var xml  = fs.readFileSync( "light_novel.xml", "utf-8" );


// load( )를 메소드를 통해 XML 데이터를 읽음

var data = cheerio.loadxml );


// 책의 정보를 표시

data( "book" ).each(function( key, val ) {

// ID 속성 취득

var bookIddataval ).attr( "id" );

// <price> 태그의 value 속성 취득

var bookPricedataval ).children( "price" ).attr( "value" );

console.log( bookId + " : " + bookPrice );

});



#05. 자식 요소 밑의 태그 검색하기

-. 위 예제에서 까지 사용한 children( ) 메서드는 자식 요소만 가져오는 요소였다.
-. 자식 아래에 있는 손자의 요소를 검색 대상으로 하고 싶은 경우에는 find( ) 메서드를 사용해야 한다.


# 소스코드

 show_books_color.js

// 모듈을 로드함

const cheerio = require( "cheerio" );

const fs = require( "fs" );


// 샘플 XML 데이터를 cheerio로 읽어들임

var xml  = fs.readFileSync( "light_novel.xml", "utf-8" );


// load( )를 메소드를 통해 XML 데이터를 읽음

var data = cheerio.loadxml );


// 책의 제목과 색을 표시

data( "book" ).each(function( key, val ) {

// <book> 태그 자식요소로부터 책의 제목 값을 취득

var bookTitledataval ).children( "title" ).text( );

// <book> 태그 자손요소로부터 책의 색상 값을 취득

var bookColordataval ).find( "color" ).text( );

console.log( bookTitle + " : " + bookColor );

});




#06. 테이블 내의 정보 가져오기


이번에는 HTML <table> 태그 안에 있는데이터를 가져오는 프로그램을 만들어 보자.

여기서는 다음과 같은 HTML 파일을 대상으로 한다.


# HTML 데이터

 marvel.html

<html>

<head>

<title>:: Marvel's The Avengers ::</title>

</head>

<body>

<table id="avenger">

<thead>

<tr><th>히어로</th><th>이름</th><th>배우</th></tr>

</thead>

<tbody>

<tr><td>아이언맨</td><td>토니 스타크</td><td>로버트 다우니 주니어</td></tr>

<tr><td>캡틴 아메리카</td><td>스티브 로저스</td><td>크리스 에반스</td></tr>

<tr><td>토르</td><td>토르 오딘슨</td><td>크리스 헴스워스</td></tr>

<tr><td>헐크</td><td>브루스 배너</td><td>마크 러팔러</td></tr>

<tr><td>블랙 위도우</td><td>나타샤 로마노프</td><td>스칼렛 요한슨</td></tr>

<tr><td>호크 아이</td><td>클린트 바튼</td><td>제러미 레너</td></tr>

<tr><td>워머신</td><td>제임스 로즈</td><td>돈 치들</td></tr>

<tr><td>팔콘</td><td>샘 윌슨</td><td>앤서니 매키</td></tr>

<tr><td>윈터 솔저</td><td>버키 반즈</td><td>세바스찬 스탠</td></tr>

<tr><td>퀵 실버</td><td>피에트로 막시모프</td><td>에런 테일러존슨</td></tr>

<tr><td>스칼렛 위치</td><td>완다 막시모프</td><td>엘리자베스 올슨</td></tr>

<tr><td>비전</td><td>완다 막시모프</td><td>폴 베타니</td></tr>

<tr><td>스파이더맨</td><td>피터 파커</td><td>톰 홀랜드</td></tr>

<tr><td>블랙 팬서</td><td>트찰라</td><td>채드웍 보스만</td></tr>

<tr><td>닥터 스트레인지</td><td>스티븐 스트레인지</td><td>베네딕트 컴버배치</td></tr>

</tbody>

</table>

</body>

</html>




# 소스코드

 read_table.js

// 모듈을 로드함

const cheerio = require( "cheerio" );

const fs = require( "fs" );


// marvel.html 파일을 읽어들임

var html = fs.readFileSync( "marvel.html", "utf-8" );


// load( )를 메소드를 통해 HTML 데이터를 읽음

$ = cheerio.loadhtml );


// 테이블 취득

var data = readTable( "#avenger" );

console.log( data );


// 테이블의 전체 셀을 읽음, table 태드를 읽어들여 2차원 배열 변수로 반환한다.

function readTable( query ) {


var data = [ ];

var table$query );

var tr_list$table ).children( "tbody" ).children( "tr" );


// 행의 갯수만큼 반복문을 실행

for( var row = 0; row < tr_list.lengthrow++ ) {

var cellstr_list.eqrow ).children( );

var cols = [ ];

// 열의 갯수만큼 반복문을 실행

for( var column = 0; columncells.lengthcolumn++ ) {

var hero = cells.eqcolumn ).text( );

cols.pushhero );

}

data.push( cols );

}

return data;

}










■ cheerio-httpcli 모듈



-. Node.js를 사용하용 스크래핑할 때 편리한 모듈이 cheerio-httpcli다.

-. cheerio-httpcli 모듈을 사용하면 파일을 손쉽게 다운로드 할 수 있을 뿐 아니라 jQuery(제이쿼리)와 비슷하게 요소를 획득할 수 있다.

-. 페이지 안의 데이터를 꺼낼 때 간편하게 지정한 요소를 추출할 수 있는 점이 가장 큰 장점이다.(웹 페이지의 문자 코드도 자동으로 판정하여 읽어 준다.)

-. 페이지 안의 링크나 이미지를 쉽게 추출할 수 있다.



#01. cheerio-httpcli 모듈 설치


 $ npm install cheerio-httpcli

 





#02. HTML 파일 다운로드


# 소스 코드

 getpage.js

// 모듈 로드

const client = require( "cheerio-httpcli" );


// 다운로드

const url = "http://magic.wickedmiso.com";

const param = { };


// fetch( ) 메서드의 인자는 URL, 파라미터, 콜백 함수의 순서로 지정한다.

client.fetchurlparam, function( error, data, response ) {

// 에러체크

if( error ) {

console.error( "Error : ", error );

return;

}

// 다운로드한 결과를 화면에 출력

var bodydata.html( );

console.log( body );

});



※ fetch( ) 메서드


 -. fetch( ) 메서드의 인자는 URL, 파라미터, 콜백 함수의 순서로 지정한다.

 -. 콜백 함수는 웹사이트에서 데이터 취득이 완료된 시점에서 실행한다.

 -. 콜백함수의 인자로는 오류 정보( error ), 취득한 데이터( data ), 서버의 응답 정보( response ), 이렇게 세가지가 주어진다.





#03. HTML 파일에서 링크 추출


cheerio-httpcli 모듈은 웹에서 HTML을 내려받은 뒤 CSS 선택자를 통해 임의의 요소를 추출하는데 사용한다.

이번에는 HTML에 링크된 URL 목록을 출력하는 프로그램을 만들어 보자.



 show-link.js

// 모듈 로드

const client = require( "cheerio-httpcli" );


// 다운로드

const url = "http://jpub.tistory.com";

const param = { };


client.fetchurlparam, function( error, dataresponse ) {

// 에러체크

if( error ) {

console.error( "Error : ", error );

return;

}

// 링크를 추출하여 표시

data( "a" ).each(function( idx ) {

var textdata( this ).text( );

var hrefdata( this ).attr( "href" );

console.log( text + " : " + href );

});

});




-. fetch( ) 메서드의 콜백 함수의 두번째 인자로 $를 지정하였는데, 이를 통해 jQuery처럼 페이지의 특정 요소를 추출할 수 있게 된다.

  ( $("a")라고 쓰면 HTML 문서 내의 모든 <a> 태그의 내용을 추출한다. )


-.  each( ) 메서드를 통해 추출한 각 요소들에 대해 지정한 함수를 수행한다.

-. 추출한 각 요소의 텍스트 부분과 href 속성의 값을 콘솔에 출력한다.




#04. HTML 파일에서 링크 추출 - 상대 URL을 절대 URL로 변경


 show-link-path.js

// 모듈 로드

const client= require( "cheerio-httpcli" );

const urlType = require( "url" );


// 다운로드

const url = "http://jpub.tistory.com";

const param = { };


client.fetch( urlparam, function( errordataresponse ) {

// 에러체크

if( error ) {

console.error( "Error : ", error );

return;

}

// 링크를 추출하여 표시

data( "a" ).each(function( idx ) {

var textdatathis ).text( );

var hrefOnedatathis ).attr( "href" );

if( !hrefOne ) {

return;

}

// 상대경로를 절대 경로로 변환

var hrefTwourlType.resolveurlhrefOne );

// 결과를 표시

console.log( text + " : " + hrefOne );

console.log( "  => " + hrefTwo + "\n" );

});

});









Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기