[JavaScript] 셀렉트 박스의 시간 자동 비교 및 선택기능[JavaScript] 셀렉트 박스의 시간 자동 비교 및 선택기능

Posted at 2019. 5. 23. 19:44 | Posted in JavaScript & jQuery/JavaScript
반응형




해당 포스팅은 제작중인 사이트 에 추가하기 위해 제작한 샘플 들이다.


페이지 접속시 시간값을 선택하는 셀렉트 박스의 경우,


바로 다음 시간대를 선택해 주는 기능과, 지나간 시간의 선택을 방지하는 기능이다.


두개의 기능을 따로따로 분리한 다음에 마지막 내용에서 합친것이니


그냥 완성된 하나가 필요한 사람의 경우 맨아래 코드를 참고하면 된다.








■ 페이지 시작시 셀렉트 박스 시간 자동선택




홈페이지에서 당일 예약을 받는 경우,


예약 가능한 다음 타임을 자동으로 선택되게끔 해야한 경우가 있어 샘플로 만들어본 코드이다.


페이지 접속과 동시에 시간을 선택하는 옵션을 가진 셀렉트 박스의 리스트 중에서


선택 가능한 다음 시간을 자동으로 선택하는 기능을 수행한다.



<html>

<head>

<title>:: JavaScript 시간 자동 선택 ::</title>

<script type="text/javascript">

document.addEventListener("DOMContentLoaded", function() {

const toDay = new Date();

const toYear = toDay.getFullYear().toString();

// getMonth()의 경우 0 ~ 11의 값을 출력하기에 기본적으로 항상 +1을 해서 한달을 더하지만

// 해당 예제에서는 그대로의 값을 필요로 하기에 +1을 하지 않는다.

// const toMonth = (toDay.getMonth() + 1).toString();

              const toMonth = toDay.getMonth().toString();

     

              const toDate = toDay.getDate().toString();

     

               /* 

                * 현재 시간(Hour)과 분(Minute)은 사용하지 않는다.

                * const toHour = toDay.getHours().toString();

                * const toMinute = toDay.getMinutes().toString();

                */

     

const toSecond = toDay.getSeconds().toString();

     

              lastTimeConstraint(toYear, toMonth, toDate, toSecond, function(lastDay) {


if(lastDay.getTime() > toDay.getTime()) { 

// 선택 가능한 선택 옵션(시간)의 갯수를 구한다.

              const timeCnt = document.getElementById("choiceTime").options.length;

              // const timeCnt = document.getElementById("choiceTime").childElementCount;

     

              const optTime = document.getElementById("choiceTime").children;

     

for(var num = 1; num <= timeCnt; num++) {

// 현재 옵션의값 value값을 추출한다.

var choTime = optTime[num].value;

var choHour = choTime.substring(0, 2);

var choMinute = choTime.substring(2, 4);

// 현재 년, 월, 일, 초의 값과 옵션의 시간, 분의 값을 날짜값으로 변경한다.

var optDay = new Date(toYear, toMonth, toDate, choHour, choMinute, toSecond);

if(optDay.getTime() > toDay.getTime()) {

document.getElementById("choiceTime").options[num].selected = true;

break;

}

}

}

else {

alert("금일 예약가능한 시간이 모두 지났습니다.\n내일 다시 예약하여 주시기 바랍니다.");

document.getElementById("choiceTime").options[0].selected = true;

return;

}

});

});

// 마지막 예약 가능 시간을 체크

function lastTimeConstraint(toYear, toMonth, toDate, toSecond, callBack) {

const lastTime = document.getElementById("choiceTime").lastElementChild.value;

const lastHour = lastTime.substring(0, 2);

const lastMinute = lastTime.substring(2, 4);

const lastDay = new Date(toYear, toMonth, toDate, lastHour, lastMinute, toSecond);

callBack(lastDay);

}

</script>

</head>

<body>

<h1>■ Part#1 시간 자동 선택</h1>

<option value="">- 선택 -</option>

<option value="0900">09:00</option>

<option value="1000">10:00</option>

<option value="1100">11:00</option>

<option value="1200">12:00</option>

<option value="1300">13:00</option>

<option value="1400">14:00</option>

<option value="1500">15:00</option>

<option value="1600">16:00</option>

<option value="1700">17:00</option>

<option value="1800">18:00</option>

</select>

</body>

</html>









■ 셀렉트 박스 선택시 선택 가능 시간 확인



<html>

<head>

<title>:: RegExp.exec() 선택 ::</title>

<script type="text/javascript">

function timeConstraint(optTime) {

const toDay = new Date();

const toYear = toDay.getFullYear().toString();

// getMonth()의 경우 0 ~ 11의 값을 출력하기에 기본적으로 항상 +1을 해서 한달을 더하지만

// 해당 예제에서는 그대로의 값을 필요로 하기에 +1을 하지 않는다.

// const toMonth = (toDay.getMonth() + 1).toString();

      const toMonth = toDay.getMonth().toString();

     

      const toDate = toDay.getDate().toString();

     

      /* 

      * 현재 시간(Hour)과 분(Minute)은 사용하지 않는다.

      * const toHour = toDay.getHours().toString();

      * const toMinute = toDay.getMinutes().toString();

      */

     

const toSecond = toDay.getSeconds().toString();

lastTimeConstraint(toYear, toMonth, toDate, toSecond, function(lastDay) {


if(lastDay.getTime() > toDay.getTime()) { 

const choHour = optTime.substring(0, 2);

const choMinute = optTime.substring(2, 4);

const optDay = new Date(toYear, toMonth, toDate, choHour, choMinute, toSecond);

if(optDay.getTime() < toDay.getTime()) {

alert("선택하신 시간은 경과하여\n예약을 진행 할 수 없습니다.");

document.getElementById("choiceTime").options[0].selected = true;

return;

} else {

alert("선택하신 시간으로\n예약이 진행됩니다.");

return;

}

}

else {

alert("금일 예약가능한 시간이 모두 지났습니다.\n내일 다시 예약하여 주시기 바랍니다.");

document.getElementById("choiceTime").options[0].selected = true;

return;

}

});

}


// 마지막 예약 가능 시간을 체크

function lastTimeConstraint(toYear, toMonth, toDate, toSecond, callBack) {

const lastTime = document.getElementById("choiceTime").lastElementChild.value;

const lastHour = lastTime.substring(0, 2);

const lastMinute = lastTime.substring(2, 4);

const lastDay = new Date(toYear, toMonth, toDate, lastHour, lastMinute, toSecond);

callBack(lastDay);

}

</script>

</head>

<body>

<h1>■ Part#2 시간 자동 선택</h1>

<select id="choiceTime" onChange="timeConstraint(this.value);">

<option value="" selected>- 선택 -</option>

<option value="0900">09:00</option>

<option value="1000">10:00</option>

<option value="1100">11:00</option>

<option value="1200">12:00</option>

<option value="1300">13:00</option>

<option value="1400">14:00</option>

<option value="1500">15:00</option>

<option value="1600">16:00</option>

<option value="1700">17:00</option>

<option value="1800">18:00</option>

</select>

</body>

</html>  










■ 시간 자동 선택 및 직접 선택시 선택가능 유무 확인





지금까지 페이지 접속시 자동 실행과


직접 선택시 해당 시간의 선택 가능 유무를 확인하는 코드를 구현해 보았다.


하지만 아마도 이렇게 선택해야 하는 경우.


위 두 코드를 따로 쓰는 경우는 별로 없을 것이다.


그래서 이제 위 두 코드를 합친 코드이고.


사실 이 포스팅을 작성하게 된 계기도 아래와 같은 기능을 구현하기 위함이었다.



# 소스 코드

<html>

<head>

<title>:: JavaScript 시간 자동 선택 ::</title>

<script type="text/javascript">

document.addEventListener("DOMContentLoaded", function() {

// 자동 시간 선택 함수 실행

autoSelectTime();

});

// 자동 시간 선택 함수

function autoSelectTime() {

// 선택 가능한 선택 옵션(시간)의 갯수를 구한다.

const timeCnt = document.getElementById("choiceTime").options.length;

// const timeCnt = document.getElementById("choiceTime").childElementCount;

     

const optTime = document.getElementById("choiceTime").children;

for(var num = 1; num <= timeCntnum++) {

var presence = timeConstraint(optTime[num].value, "auto");


if(presence == "success") {

document.getElementById("choiceTime").options[num].selected = true;

break;

} else if(presence == "unknown") {

break;

}

}

}

// 자동 시간 선택 함수

// optTime : 선택된 option의 value값

// motion :  자동 실행의 호출(auto)인지, 직접 선택한 경우의 호출(passive)인지의 구분

function timeConstraint(optTime, motion) {

const toDay = new Date(); // 현재 날짜

const toYeartoDay.getFullYear().toString(); // 현재 년도

// getMonth()의 경우 0 ~ 11의 값을 출력하기에 기본적으로 항상 +1을 해서 한달을 더하지만

// 해당 예제에서는 그대로의 값을 필요로 하기에 +1을 하지 않는다.

// const toMonth = (toDay.getMonth() + 1).toString();

              const toMonthtoDay.getMonth().toString(); // 현재 월(자바스크립트의 특성상 지난 달)

     

              const toDatetoDay.getDate().toString(); // 현재 일

     

              /* 

               * 현재 시간(Hour)과 분(Minute)은 사용하지 않는다.

               * const toHour = toDay.getHours().toString();

               * const toMinute = toDay.getMinutes().toString();

               */

     

const toSecondtoDay.getSeconds().toString(); // 현재 초

const choHouroptTime.substring(0, 2); // 옵션의 시간

const choMinuteoptTime.substring(2, 4); // 옵션의 분

// 셀렉트 박스의 옵션 값을 시간값으로 포맷한다.

const optDay = new Date(toYeartoMonthtoDatechoHourchoMinutetoSecond);


// 리턴할 값을 담을 변수 지정

let presence = "";


// 계속되는 반복 작업을 막기위해, 먼저 금일 마지막 시간이 이미 지났는지 여부를 확인한다.

lastOptionTime(toYeartoMonthtoDatetoSecond, function(lastDay) {

// 마지막 예약 시간이 지나지 않은경우

if(lastDay.getTime() > toDay.getTime()) { 

const choHouroptTime.substring(0, 2);

const choMinuteoptTime.substring(2, 4);

// 선택한 옵션의 시간값을 날자 값으로 포맷한다.

const optDay = new Date(toYeartoMonthtoDatechoHourchoMinutetoSecond);

// 현재시간이 옵션의 시간보다 큰경우

if(optDay.getTime() < toDay.getTime()) {

if(motion == "passive") {

alert("선택하신 시간은 경과하여\n예약을 진행 할 수 없습니다.");

// 사용자가 직접 시간을 선택하였으나 이미 시간이 경과한경우 예약 가능한 시간을 찾기위해

// autoSelectTime() 함수를 실행한다.

autoSelectTime();

}

presence = "failure";

}

// 사용가능 한 시간

else {


if(motion == "passive") {

alert("선택하신 시간으로\n예약이 진행됩니다.");

}

presence = "success";

}

}

// 마지막 시간이 지난 경우

else {

document.getElementById("choiceTime").options[0].selected = true;

alert("금일 예약가능한 시간이 모두 지났습니다.\n내일 날자로 예약하여 주시기 바랍니다.");

presence = "unknown";

}

});

return presence;

}


// 마지막 예약 가능 시간을 체크하는 함수

function lastOptionTime(toYeartoMonthtoDatetoSecond, callBack) {

// 마지막 option 엘리먼트의 value값을 가져온다.

const lastTime = document.getElementById("choiceTime").lastElementChild.value;

const lastHourlastTime.substring(0, 2);

const lastMinutelastTime.substring(2, 4);

// 마지막 option의 value값(시간)을 날자값으로 포맷한다.

const lastDay = new Date(toYeartoMonthtoDatelastHourlastMinutetoSecond);

callBack(lastDay);

}

</script>

</head>

<body>

<h1>■ 시간 자동 선택 Part3</h1>

<select id="choiceTime" onChange="timeConstraint(this.value, 'passive');">

<option value="" selected>- 선택 -</option>

<option value="0900">09:00</option>

<option value="1000">10:00</option>

<option value="1100">11:00</option>

<option value="1200">12:00</option>

<option value="1300">13:00</option>

<option value="1400">14:00</option>

<option value="1500">15:00</option>

<option value="1600">16:00</option>

<option value="1700">17:00</option>

<option value="1800">18:00</option>

</select>

</body>

</html>  





# 출력 결과







반응형
//

[Puppeteer] 페이지 클릭 및 입력 이벤트[Puppeteer] 페이지 클릭 및 입력 이벤트

Posted at 2019. 5. 10. 18:31 | Posted in Node.js/Puppeteer
반응형





■ 페이지의 특정 영역 클릭 이벤트




퍼펫티어에서 클릭 이벤트는 해당 앨리먼트를 셀렉터 값을 설정하고 click( ) 메서드로 실행시키기만 하면 된다.



# 소스 코드

 tommorrow_weather.js

const puppeteer = require( "puppeteer" );


puppeteer.launch({

headless : false

}).then(async browser => {


const page = await browser.newPage();

await page.goto( "https://weather.naver.com/", { waitUntil : "networkidle2" } );


page.waitForNavigation( ), // 해당 페이지의 탐색이 완료되면 클릭 이벤트를 실행

page.click( "div.weather_info > div.w_map > ul.tab > li:nth-child(4) > a" ); // 클릭이벤트를 실행

});




# 출력 결과

 $ node tomorrow_weather.js 









■ 페이지의 특정 영역에 값 입력 하기




#01. input 박스에 값 입력하기



위 예제에서는 click( 앨리먼트 ) 를 지정하여 손쉽게 클릭 이벤트를 진행 할 수 있었다.


입력도 이와 마찬기자로 type( ) 메서드에 앨리먼트의 셀렉터 주소와 입력 값을 지정해 주는것으로 손쉽게 진행할 수 있다.




# 소스 코드

 twitter_login.js

const puppeteer = require( "puppeteer" );


puppeteer.launch({

headless : false

}).then(async browser => {


const page = await browser.newPage();

await page.goto("https://twitter.com/login?lang=ko", { waitUntil : "networkidle2" } );

// 트위터 아이디 값 입력

await page.type( "div.clearfix:nth-child(2) > input", "트위터 아이디" );

// 트위터 패스워드 패스워드 값 입력

await page.type( "div.clearfix:nth-child(3)> input", "트위터 패스워드" );

// 트위터 로그인 버튼 클릭

await page.click( "button.submit" );

});




# 출력 결과

 $ node twitter_login.js







#02. 키보드로 직접 입력하는것과 같은 이벤트


이전에 page.type(엘리먼트, 입력값)과 같은 형태로 input 타입에 값을 입력 할 수 있었다.


그렇지만 직접 키보드를 입력해야 하는 것과 같은 자연스러운 입력이 필요한 경우가 존재하기에 추가적으로 작업을 더 해보려고 한다.



# 소스 코드

 facebook_login.js

const puppeteer = require( "puppeteer" );


puppeteer.launch({

headless : false

}).then(async browser => {


const page = await browser.newPage();

await page.goto( "https://www.facebook.com/", { waitUntil : "networkidle2" } );

// 페이지가 전부 로드된 이후 작업 실행

await page.waitForNavigation( );

// 페이스북 이메일 입력 부분 클릭

await page.click( "input#email" );

// 페이스북 아이디를 키보드로 입력한다.

await page.keyboard.type( "페이스북 이메일 주소" );

// TAB 버튼을 클릭하여 바로 옆에있는 패스워드 입력 영역으로 커서를 이동시킨다.

await page.keyboard.press( "Tab" );

// 페이스북 패스워드를 키보드로 입력한다.

// 이때 자연스러운 입력을 버튼을 하나씩 입력할때마다  DELAY를 통한 시간차가 있게끔 설정한다.

await page.keyboard.type( "페이스북 패스워드", { delay : 100 } ); // 시간은 밀리세컨드(ms) 단위로 계산된다.

// TAB 버튼을 클릭하여 좌측에 존재하는 로그인 버튼이 선택되게 한다.

await page.keyboard.press( "Tab" );

// ENTER 키를 클릭하여 로그인한다.

await page.keyboard.press( "Enter" );

});





# 출력 결과

 $ node facebook_login.js






위와같이 트위터와 페이스북에 손쉽게 로그인 할 수 있었다.


그렇지만 보안이 중요한 사이트의 경우 키보드의 물리 입력을 감지하거나 하는 형식으로


작업을 진행하는 경우가 존재하는데, 이 경우 위와같은 입력 및 클릭방법은 전혀 도움이 되지 못한다.


그러한 경우는 아래 글을 참고하자.








■ 키보드 보안을 우회하기 위한 방법




원문 : https://2cpu.co.kr/bbs/board.php?bo_table=QnA&wr_id=591362












반응형
//

[Node.js] Terminal 명령을 수행하는 node_cmd 모듈[Node.js] Terminal 명령을 수행하는 node_cmd 모듈

Posted at 2019. 5. 10. 16:22 | Posted in Node.js
반응형




참고 : https://www.npmjs.com/package/node-cmd




■ 노드에서 터미널 명령 실행을 하게 해주는 node-cmd 모듈




node_cmd는 nodejs의 실행프로그램에서 터미널( or 명령프롬프트)에서 다른 node 모듈을 실행시킬 수 있다.



# node-cmd 설치

 $ npm install node-cmd




터미널 명령을 수행할 노드 실행 파일을 아래와 같이 생성한다.



# 소스 코드① - 터미널 명령 수행

 node_cmd.js

var cmd = require( "node-cmd" );

 

cmd.get(

  // 실행할 노드 실행 파일

  "node console_log.js"

, function( error, success, stderr ) {


        if( error ) {

        console.log( "ERROR 발생 :\n\n", error );

    } else {

        console.log( "SUCCESS :\n\n", success );

    }

    }

);



다음으로 node_cmd.js 에서 실행할 node 실행파일을 하나더 만든다.





# 소스 코드② - 테스트 노드 파일

 console_log.js

console.log("do you guys not have phones");





# 실행 결과

 $ node  node_cmd.js

 









반응형
//

[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" );

});

});









반응형
//