특정 웹 페이지를 스크래핑 하던 중, 스크래핑이 중단된 경우가 있어 정리하기 !!!
일단 크롤링과 스크래핑의 차이가 궁금해서 찾아봤다.
크롤링
웹 크롤링은
URL을 탐색해 반복적으로 링크를 찾고 가져오는 과정
으로, 웹 페이지를 직접 찾아다니면서 정보를 수집하는 동작을 말한다. 크롤링 시중복 제거
는 필수로 진행한다.
스크래핑
웹 스크래핑은
우리가 정한 특정 웹 페이지에서 데이터를 추출하는 것
으로, 사용자가 원하는 특정 주제의 뉴스만을 가져오거나, 가격을 모니터링 하는 등의 동작을 말한다. 스크래핑의 경우중복 제거
는 필수가 아니다.
크롤링
과 스크래핑
모두 정보를 추출한다
는 동작은 같지만, 타켓 웹 사이트
의 유무와 중복제거
유무에서 차이를 보인다고 한다~
이제 본론으로 들어가서, 나는 Node.js를 이용해서 매일 오후 1시에 스크래핑을 진행하고, 스크래핑 한 결과를 DB에 저장 시키고 있었다.
홈페이지 크롤링을 위한 모듈로는 cheerio
를 사용하고 있었는데, 어느순간 결과값이 저장되지 않고 있었다.
스크래핑 되고 있는 HTML 코드를 console 창에 출력시켜 보니, 단순 뼈대만 계속해서 긁어오고 있어 내가 원하는 결과값을 하나도 가져오지 못하고 있었다 !
아마 홈페이지가 정적에서 동적으로 전환되면서 발생한 문제인 것 같다~~
내가 사용했던 cheerio
모듈은 정적 페이지를 크롤링 하는데는 유용하지만, 동적 페이지 크롤링에는 한계가 있다고 하여 puppeteer
모듈을 설치하였다.
npm install puppeteer
로 node에 puppeteer 모듈을 설치 해 주었고,
const puppeteer = require('puppeteer');
크롤링을 진행하는 js 파일 상단에 해당 구문을 추가 해 주었다.
cheerio 모듈을 사용 할 때에는
const testPage = await rp.get('https://www.naver.com/');
const $ = cheerio.load(testPage);
이런식으로 간단하게 페이지를 스크래핑 할 수 있었는데, puppeteer 모듈을 추가 하면서 약간 복잡해졌다.
(async() => {
try {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.naver.com/');
const content = await page.content();
const $ = cheerio.load(content);
await browser.close();
} catch (err) {
console.error(err);
}
})();
이렇게 추가하면 동적 페이지를 스크래핑 할 수 있다! 물론 naver 페이지는 예시로 추가한거고, 원하는 페이지 주소를 넣어주면 된다.
아마 content 값을 받아 온 뒤에 cheerio로 다시 로드 하는 방식으로 하는 것 같은데 어렵다🧐
하여튼 이렇게 하면 동적페이지도 수월하게 크롤링 할 수 있다~~!
추가로, 나는 특정 버튼이 눌릴 때 마다 HTML 코드가 바뀌는 경우가 있었는데,
const buttons = await page.$$('.button_class');
for (const button of buttons) {
await button.click();
await page.waitForTimeout(1000);
console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
const pageContent = await page.content();
const $ = cheerio.load(pageContent);
}
위 처럼 작성하니 class명이 button_class인 버튼이 눌릴 때마다의 동적 HTML 코드를 크롤링 해 올수 있었다!!
각 버튼을 클릭하고 나서 1초 대기한 뒤 HTML 코드를 load 할 수 있었다. chatGPT가 알려줬다😁
이제 HTML 코드는 원활하게 가져오고 있으니, 내가 원하는 값을 가져오기 위한 코드만 하단에 작성 해 주면 끝이당🤩