Puppeteer 간단 정리하기

박성룡 ( Andrew park )
7 min readSep 8, 2019

--

Puppeteer 에 대해서 익히고, 배운것을 간단하게 정리해보고자 한다.

Puppeteer 는 Headless Chrome 혹은 Chromium 를 제어하도록 도와주는 라이브러리 이다.

Chrome 59 부터 Headless 을 지원한다.

Puppeteer 는 Node 6 이상 에서 동작하며, Chrome 혹은 Chromium 의 DevTools 프로토콜 을 통해 각 Chrome 혹은 Chromium 의 API 제어한다.

Puppeteer 기능

아래의 기능을 구현해 볼 수 있다.

  • SPA 화면의 렌더링이 가능하다
  • 렌더링후 키보드, 마우스 입력 제어할 수 있다.
  • 웹페이지의 자동 테스트 도구를 만들 수 있다.
  • 각각의 웹페이지 crawling 이 가능하다.
  • 접속한 페이지를 스크린샷을 찍거나 PDF 으로 만들 수 있다.

Headless Browser

Headless Browser 는 CLI (Command Line interface) 에서 작동하는 브라우저이다.

일반적으로 사용자가 사용하는 GUI 에서 동작하는 브라우저가 아니다.

백그라운드에서 동작하며, 일반적인 브라우저와 같이 웹페이지에 접속하여 HTML, CSS 으로 DOM Tree 와 CSSOM Tree 를 만들고, JS 엔진을 구동한다.

유일한 차이점은 만든 화면을 사용자에게 보여주지 않는다는 점이다.

일반 브라우저와 큰 차이가 없기 때문에 보여주는 화면이 없이도, 화면 테스트나 스크린샷을 찍는것등 다양한 기능 동작이 가능하며, 사용자가 실제 사용하는 환경과 비슷하게 테스트가 가능하다.

Puppeteer 특징

puppeteer 에서는 Chrome 혹은 Chromium 의 렌더링 엔진을 사용하여, Headless Browser 환경을 구성하였다.

2017년 Google Chrome 59버전 부터 Headless Chrome 이 내장되었고, 얼마후 Google 에서 puppeteer 를 발표하였다.

puppeteer 는 Chrome 혹은 Chromium 의 렌더링 엔진을 이용한다.

Chrome 의 렌더링 엔진이 지원하는 최신 스펙의 HTML, CSS, JS 등 렌더링 엔진이 만들 수 있는 모든 화면을 만들어 낼 수 있다.

여러 ifream 이나 popup 으로 이루어진, 복잡한 화면을 제어하는 것이 가능하며, 최근 ES6로 작성된 SPA 화면 들도 렌더링 및 제어가 가능하다.

puppetter 는 DevTools 프로토콜을 이용하여, 직접 Chrome 을 제어하고, 사용할 수 있도록 개발되었다.

DevTools 프로토콜 으로 Mouse 와 Keyboard 뿐만 아니라, 브라우저 스크린 크기, 쿠키 및 세션 스토리지, 심지어 서비스 워커도 제어가 가능하다.

puppeteer 는 직접 Chrome 을 구동하여, DevTools 프로토콜로 제어하여, 사용자들이 직접 사용하는 환경과 비슷하게 동작하는 것을 직접 보면서, 확인 할 수 있다.

설치 ( puppeteer 와 puppeteer-core )

puppeteer 를 사용하기 위해서는 Chrome 이나 Chromium 이 필요하다.

1.7.0 이후 버전 부터는 puppeteer 와 puppeteer-core 2가지 버전을 제공한다.

기능은 비슷하지만, 중요한 차이점은 core 은 Chromium 을 포함하지 않고, PUPPETEER_* 환경 변수들을 사용하지 않는다.

npm 을 통해 puppeteer 를 다운로드 할 때, Chromium 포함하지만, puppeteer-core 로 다운로드 할 경우 이 Chromium 을 제외할 수 있다.

puppeteer-core 는 로컬에 설치 되어 있는 Chrome 브라우저 를 연결하여, 실행한다.

구조

Puppeteer API는 계층적이다.

  • puppeteer 는 하나의 Browser 를 갖는다.
  • 하나의 Browser 는 여러 BrowserContext 를 가질 수 있다.
  • 하나의 BrowserContext 여러 Page 를 가질 수 있고, Serviceworker 와 Session 을 가질 수 있다.
  • 하나의 Page 는 여러 Frame 을가질 수 있다.
  • 하나의 Frame 은 여러 Context 를 가질 수 있다.
https://pptr.dev/#?product=Puppeteer&show=api-overview

BrowserContext

puppeteer 로 Browser가 시작되면 default BrowserContext 가 생성된다.

이 default BrowserContext 는 Browser 의 생명주기와 같다.

Browser 는 여러 개의 BrowserContext를 가질 수 있다.

Browser.createIncognitoBrowserContext() 으로 시크릿 브라우저 컨텍스트를 만들 수 있다.

window.open 호출로 생성된 팝업은 이전 페이지의 BrowserContext 에 속한다.

Browser.newPage() 로 생성된 페이지는 default BrowserContext 에 포함된다.

기본 예제

아래는 example 페이지에 접속하여 스크릿 샷을 찍는 예제이다.

// https://developers.google.com/web/tools/puppeteer/get-started
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();

대부분의 메소드들은 Promise 를 반환한다.

puppeteer.launch() 메서드를 통해 browser 를 생성할 수 있다.

이때, 옵션을 전달하여 브라우저를 제어할 수 있다.

  • headless: 기본값은 true 이고, false 로 설정하면, 브라우저가 실행된다.
  • defaultViewport: 기본값은 800x600 이고, 화면이 노출될 사이즈를 지정할 수 있다.
  • devtools: 기본값은 false 이고, true 로 설정하면, 브라우저에 Devtools 가 열린다.

이 외에도 많은 옵션이 제공된다.

생성된 browser 으로 browser.newPage() 메서드를 통해 page 를 생성할 수 있다.

생성된 page 로 실제 페이지를 조작 및 제어 할 수 있다.

page.goto 메서드로 페이지를 이동할 수 있다.

page 에서 $, $eval으로 Element 를 선택 할 수 있는데, 이때 선택자는 jQuery 에서 많이 사용되었던, CSS selectors 로 선택 할 수 있다.

만약 여러개가 선택된다면, 첫번째 인자를 선택한다.

$$, $$eval 로 다중 선택할 수 있는데, 이때 배열로 반환된다.

$ 와 $eval 의 차이는 $ 는 Element 를 반환하고, $eval 는 콜백함수를 전달하고, Element 를 인자로 받는다.

page.screenshot 으로 해당 페이지의 스크린샷을 찍어서 특정 path 에 저장할 수 있다.

type 키보드 입력, click 클릭, hover 마우스 호버 등 다양한 방법으로 페이지를 조작할 수 있다.

마무리

puppeteer 에 대해서 간단하게 알아보았다.

puppeteer 는 Headless Chrome 을 제어하도록 도와주는 라이브러리일 뿐이다.

이것을 어떻게 이용 할지는 오로지 개발자의 몫이다.

여러가지 방법으로 만들수 있게 도와주는 강력한 툴 이라 앞으로 배우고 익히면 많은 도움이 될 것같다.

특히 구글에서 만들었기 때문에, 지속적은 서포트가 있을 것으로 예상되어 더 기대가 된다.

다음 포스트로 자동화된 테스트를 만들고 그 삽질기를 공유해 보고 싶다.

--

--