Miracle Morning, LHWN

8. puppeteer 을 이용한 동적 Crawling 본문

IT 기술/[React] Project

8. puppeteer 을 이용한 동적 Crawling

Lee Hye Won 2021. 6. 1. 14:39

네이버 블로그를 크롤링하는 과정에서 cheerio 로는 크롤링이 제한되는 상황이 나왔다.

첫 로딩된 HTML 에는 해당 element 가 display:none; 상태로 있었고, 특정 버튼을 눌러야 해당 element 가 나타났다.

다만, cheerio 를 이용한 크롤링은 DOM (Document Object Model: 웹 페이지에 대한 인터페이스) 이 계속 변하는 SPA (Single Page Application: 단일 페이지 어플리케이션) 에서는 사용할 수가 없어 puppeteer 를 추가적으로 사용하였다.

 

cheerio 와 puppeteer 의 차이

 

cheerio 는 jQuery 를 이용해서 웹 페이지를 parsing 하고, 데이터 구조의 결과물을 탐색 및 조작할 수 있도록 도와주는 Node.js 의 라이브러리이다. 일반적으로 jQuery Selector $ 에 load 된 HTML 값을 넣어 사용한다.

const $ = cheerio.load(html.data);
const $postList = $('div.se-section-documentTitle');

puppeteer 은 Chrome 또는 Chronium 을 제어할 수 있는 high-level 의 API 를 제공하는 Node.js 의 라이브러리이다.

기본적으로 headless browser 에서 동작하지만 full (non-headless) Chrome 에서도 동작할 수 있다.

(async () => {
  const browser = await puppeteer.launch(); // 브라우저 실행 (여기서 headless:false 속성을 주면 브라우저가 열리고 닫히는 과정을 시각적으로 볼 수 있다.
  const page = await browser.newPage(); // 새로운 페이지 열기
  await page.setViewport({
    width: 1920,
    height: 1080
  });
  // 지정된 URL 접속
  await page.goto('URL...');
  await page.click('#category-name > div > table.post-body > tbody > tr > td.bcc > div > a');

  await page.waitForSelector('#listTopForm > table');
  const data = {};
  const temp = await page.$('#listTopForm > table > tbody > tr:nth-child(1) > td.title');
  data.hits = await page.evaluate((data) => {
    return data.textContent;
  }, temp);
  await browser.close();
})();
// 전체 HTML 을 가져올 때
  let html = [];
  const response = await page.content('https://blog.naver.com/PostList.nhn?blogId=wlsekffo1674&widgetTypeCall=true&directAccess=true');
  html.push(response);

 

※ 여기서 headless browser 란?

'창이 없는 브라우저'라고 이해하면 된다. 보통 웹 브라우저는 GUI (Graphic User Interface) 를 이용하여 창을 띄우고 동작하는데,

headless browser 는 GUI 없이 프로그램 상으로만 동작한다.

실제 브라우저와 동일하게 동작하지만 창은 뜨지 않고 화면을 그려주는 작업 즉, 렌더링을 가상으로 진행해주어 사이트를 크롤링하거나

스크린샷을 찍을 때 유용하고 브라우저 테스트할 때도 훨씬 빠르게 테스트할 수 있다.


참고 : https://velog.io/@sue517/cheerio-vs-puppeteer

 

Comments