유명한 크롤러 라이브러리로 Selenium이 있지만
Node.js로 웹 개발을 진행중이여서 노드 라이브러리를 찾게 되었다.
2017년 구글에서 만들어 낸 노드를 위한 웹 스크래핑 서비스 이며
예시로 크롤러가 사람처럼 input에 값을 넣고 로그인 버튼을 눌러준 후 페이지를 이동해 크롤링을 해올 수 있는 똑똑한 친구다.
공식 레퍼런스 또한 정리가 잘 되어있다.
https://pptr.dev/
42GG
사이트를 제작 중 42API
를 통해 카뎃 목록을 불러오려 하였는데
호출된 데이터에는 카뎃과 비 카뎃을 구분지을 수 없었다..
그래서 인트라 Grade
목록에서 해당 유저가 Learner
인지 Novice
인지 체크하는 검증 단계를 거치려고 크롤링을 공부하게 되었다.
npm i puppeteer
const puppeteer = require("puppeteer");
const getData = async () => {
// 브라우저를 열어준다
const browser = await puppeteer.launch();
// 새 창을 띄운다
const page = await browser.newPage();
// 로그인을 위한 아이디, 비밀번호
const login = "아이디";
const password = "비밀번호";
// 인트라 로그인 페이지 연결
await page.goto("https://signin.intra.42.fr/users/sign_in");
// 아이디, 비밀번호에 입력 (태그만 찾아주면 알아서 입력한다)
await page.evaluate(
(id, pw) => {
document.querySelector('input[name="user[login]"]').value = id;
document.querySelector('input[name="user[password]"]').value = pw;
},
login,
password
);
// 로그인 버튼 클릭
await page.click('input[name="commit"]');
// puppeteer 에게 기다리라고 하는 함수 (default: 300000ms)
// await page.waitForTimeout(5000);
// 로그인 실패한 경우 (이미 로컬에 로그인 되어있는 브라우저가 열려있다던지 ..)
if (page.url() === "https://signin.intra.42.fr/users/sign_in") {
console.log("로그인 실패");
}
// 로그인 성공
else {
// 유저정보의 Grade란이 필요하니 유저정보 페이지로 이동
await page.goto(`https://profile.intra.42.fr/users/유저명`);
// $ 는 document.querySelector 과 같은 역할을 한다
// $$ 는 document.querySelectorAll 과 같은 역할을 한다
const crawl = await page.$(
"body > div.page > div.page-content.page-content-fluid > div > div.container-item.full-width.profile-item.profile-on-users > div > div.profile-left-box > div.user-primary > div > div.user-infos-sub.margin-top-10 > div:nth-child(5) > span.user-grade-value"
);
// 해당 태그의 value를 반환한다
const grade = await page.evaluate((element) => {
return element.textContent;
}, crawl);
}
}
// 브라우저를 닫아준다
await browser.close();
}
사실 인트라에서 유저 등급을 얻어온다는 아이디어가 좋다 생각해 크롤링을 시작했지만..
너무 느린 인트라 환경 덕에 유저 한명의 등급을 얻어오는데 평균 10초 가량 소비되었다 😕
참 좋은 크롤러지만 정보 하나 받아오는데 너무 긴 관계로 포기하고
귀찮지만 api로 하나하나 받아오면서 검증을 해야겠다 🥲