ETOOS Daily Test Management System(가칭)
진행 중에 네이버 부스트 캠프 공고를 보고 그 날부터
코딩테스트 준비하랴 출퇴근하랴 아주 난리도 아니었다.
그렇게 멀리멀리 미뤄질 뻔 했던 프로젝트는 불행인지 다행인지
부스트 캠프 지원서에 포트폴리오로 첨부하기 위해
다시 붙잡게 되었다!
오전에는 학원에서 일하면서 프로젝트 진행하고
퇴근하곤 집에와서 코딩테스트 준비
반복의 굴레 속에 살고있다.....하하
하지만 잼써!
이런 식으로 각 페이지 Table 추출한다!
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless : false,
defaultViewport : null,
});
const page = await browser.newPage();
await page.goto('https://www.etoos.com/member/login.asp?returnUrl=http://247.etoos.com/lms/index.do');
await page.waitForNavigation;
// ID, PW 입력
await page.type('#mem_id', 'ID');
await page.type('#pwdtmp', 'PW');
// 로그인 버튼 클릭
await page.click('.btn_login');
await page.waitForNavigation;
// selector 를 누르기 전 selector를 찾아야하므로 waitForSelector 를 준 다음 click
await page.waitForSelector('#lnbmenu > ul > li:nth-child(2) > a');
await page.click('#lnbmenu > ul > li:nth-child(2) > a');
await page.waitForTimeout(2000);
// waitForTimeout() 줘서 안정적으로 selector 를 찾게함
await page.waitForSelector('#m_PB200717 > a');
await page.click('#m_PB200717 > a');
await page.waitForNavigation;
// 달력 5/1 이동
await page.waitForSelector('#records_form > div > img:nth-child(3)');
await page.click('#records_form > div > img:nth-child(3)');
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(1) > td:nth-child(7) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(1) > td:nth-child(7) > a');
await page.waitForSelector('#btn_search');
await page.click('#btn_search');
await page.waitForNavigation;
for(let i =2; i<12; i++){
// page 1 ~ 10 Table 추출
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
if(i===11){
// 10페이지 Table 추출 후 11페이지로 넘어감
await page.waitForTimeout(2000);
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
// page 11 ~ 20 Table 추출
for(let j=3; j<13; j++){
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
}
break;
}
}
// 달력 5/9 이동
await page.waitForSelector('#records_form > div > img:nth-child(3)');
await page.click('#records_form > div > img:nth-child(3)');
// 5월 9일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(3) > td:nth-child(1) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(3) > td:nth-child(1) > a');
// 5월 16일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(4) > td:nth-child(1) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(4) > td:nth-child(1) > a');
// 검색
await page.waitForSelector('#btn_search');
await page.click('#btn_search');
await page.waitForNavigation;
for(let i =2; i<12; i++){
// page 1 ~ 10 Table 추출
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
if(i===11){
// 10페이지 Table 추출 후 11페이지로 넘어감
await page.waitForTimeout(2000);
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
// page 11 ~ 20 Table 추출
for(let j=3; j<13; j++){
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
}
break;
}
}
// 달력 5/17 이동
await page.waitForSelector('#records_form > div > img:nth-child(3)');
await page.click('#records_form > div > img:nth-child(3)');
// 5월 17일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(4) > td:nth-child(2) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(4) > td:nth-child(2) > a');
// 5월 24일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(5) > td:nth-child(2) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(5) > td:nth-child(2) > a');
// 검색
await page.waitForSelector('#btn_search');
await page.click('#btn_search');
await page.waitForNavigation;
for(let i =2; i<12; i++){
// page 1 ~ 10 Table 추출
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
if(i===11){
// 10페이지 Table 추출 후 11페이지로 넘어감
await page.waitForTimeout(2000);
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
// page 11 ~ 20 Table 추출
for(let j=3; j<13; j++){
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
}
break;
}
}
// 달력 5/25 이동
await page.waitForSelector('#records_form > div > img:nth-child(3)');
await page.click('#records_form > div > img:nth-child(3)');
// 5월 25일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(5) > td:nth-child(3) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(5) > td:nth-child(3) > a');
// 5월 31일 클릭
await page.waitForSelector('#ui-datepicker-div > table > tbody > tr:nth-child(6) > td:nth-child(2) > a');
await page.click('#ui-datepicker-div > table > tbody > tr:nth-child(6) > td:nth-child(2) > a');
// 검색
await page.waitForSelector('#btn_search');
await page.click('#btn_search');
await page.waitForNavigation;
for(let i =2; i<12; i++){
// page 1 ~ 10 Table 추출
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
if(i===11){
// 10페이지 Table 추출 후 11페이지로 넘어감
await page.waitForTimeout(2000);
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
// page 11 ~ 20 Table 추출
for(let j=3; j<13; j++){
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
}
break;
}
}
await browser.close();
})();
이전 코드에서는 월 별 1일 첫 번째 페이지에 로딩되는 테이블을 크롤링해왔는데
몇 페이지를 나타내는 selector -> a:nth-child(i) 를 찾아
for() 반복문을 이용해
1~10페이지 탐색 후 데이터 추출 -> 11~20페이지 탐색 후 데이터 추출 -> break
순으로 코드를 작성해보았다.
for(let i =2; i<12; i++){
// page 1 ~ 10 Table 추출
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ i +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
if(i===11){
// 10페이지 Table 을 추출하고 나서 시행되는 code
await page.waitForTimeout(2000);
// 10 페이지에서 11페이지로 넘어가는 button
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a.btn_next');
// page 11 ~ 20 Table 추출
for(let j=3; j<13; j++){
await page.waitForSelector('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.click('#container > div.contents > div.btn_area.mgt_15 > div > a:nth-child('+ j +')');
await page.waitForSelector('#container > div.contents > div.wrap_tbl_sdw.mgt_30');
const data = await page.evaluate(()=>{
const tds = Array.from(document.querySelectorAll('#container > div.contents > div.wrap_tbl_sdw.mgt_30'));
return tds.map(td => td.innerText);
});
console.log(data)
}
break;
}
}
아직 모자란 부분이 너무 많다.
반복되는 부분(월 별 1주일 단위로 넘어가는 부분)을
하나의 function 으로 만들어서 표현하고 싶었는데
표현이 잘 되지 않는다.
코딩테스트 준비하면서 배웠던 부분을 더 다듬어서 이 프로젝트에 쏟아내고 싶다!