Headless 크롬 Node 라이브러리 Puppeteer 사용해보기

 

Puppeteer

Headless Chrome Node APIPuppeteer는 Chrome Chrome 팀에서 개발한 Chrome Headless를 위한 official tool입니다.

Puppeteer의 대표적인 기능입니다.

  • 페이지 스크린샷, PDF 생성
  • SPA (Single-Page Application) 크롤링
  • 크롬 확장프로그램 테스트

자세한 내용은 Puppeteer Github에서 볼 수 있습니다.

라이브러리가 굉장히 직관적이면서, DOCS도 잘 설명이 되어있어서 사용도 굉장히 쉬웠습니다. 그렇지만, 아직 오픈소스 라이브러리 사용에 어려움을 겪는 분들을 위해 간단하게 사용하는 방법과 결과물을 포스팅 합니다.

사용해보기

Puppeteer를 사용하기 위해 npm으로 설치합니다.

npm i puppeteer

구글에 접속해서 스크린샷을 찍어보는 코드를 작성합니다. 코드에 대한 자세한 설명은 공식 docs를 참고하길 바라며, 간단한 설명은 주석으로 적어두었습니다.

//puppeteer require
const puppeteer = require('puppeteer');

(async () => {
    //브라우저 오픈
    const browser = await puppeteer.launch();
    //페이지 오픈
    const page = await browser.newPage();
    //url로 이동
    await page.goto('https://google.com');
    //스크린샷을 dalhav.png로 저장
    await page.screenshot({path: 'dalhav.png'});
    //브라우저 종료
    await browser.close();
})();

코드로 작동되어 결과로 나온 스크린샷입니다. Default로 800px X 600px로 설정되어있어서 짤려서 캡쳐되었습니다.

1

스크린샷의 크기는 .setViewport 를 사용하여, 고정 크기를 변경할 수 있습니다. 저는 브라우저 페이지 전체를 캡쳐하고 싶어 fullPage: true 옵션을 사용해보았습니다.

    //풀페이지 스크린샷을 dalhav.png로 저장
    await page.screenshot({path: 'dalhav.png', fullPage: true});

위의 스크린샷과 달리 풀페이지가 캡쳐되었습니다. 구글처럼 가로가 긴 사이트뿐만 아니라 세로가 길어서 스크롤을 해야하는 사이트도 fullPage: true 옵션으로 캡쳐해보면 풀페이지가 캡쳐되는 것을 볼 수 있습니다.

2

사진이 아닌 pdf로 출력할 수도 있습니다. pdf 옵션은 Page.pdf() 에서 확인할 수 있습니다.

//스크린샷을 pdf로 저장
    await page.pdf({path: 'dalhav.pdf'});

3

Puppeteer로 웹 크롤링을 할 수 있습니다.
구글에서 dalha.v blog를 검색해서 나온 결과에서 제목콘솔에 출력하고, 검색결과를 스크린샷으도 출력하는 코드입니다.

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    await page.goto('https://google.com');
    await page.keyboard.type('dalha.v blog');
    await page.keyboard.press('Enter');
    await page.waitForSelector('h3', {timeout: 10000});
    const result = await page.evaluate(() => {
        const anchors = Array.from(document.querySelectorAll('h3'));
        return anchors.map(anchor => anchor.textContent);
    });
    await page.screenshot({path: 'dalhav_google_search.png'});
    console.log(result.join('\n'));
    await browser.close();
    })();

실제 콘솔에 출력된 결과와 스크린샷입니다.

4

DALHA.V Blog
DALHA.V Blog - GitHub Pages
MongoDB - DALHA.V Blog
Algorithm - DALHA.V Blog
Node.js 기반 홈페이지 만들기 (2) - Crypto, Passport - DALHA.V Blog
Kakao - DALHA.V Blog
활동 - DALHA.V Blog
동영상
dalha.v blog 관련 이미지

이와 비슷하게 유튜브도 검색할 수 있습니다.
유튜브에 Supply chain attack_demon 1을 검색해서 검색 결과 리스트를 스크린샷으로 출력하고, 검색 결과의 첫번째 영상을 클릭한 화면을 스크린샷으로 출력하는 코드입니다.

const puppeteer = require('puppeteer');

try {
    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://youtube.com');
        await page.type('#search', 'Supply chain attack_demon 1');
        await page.click('button#search-icon-legacy');
        await page.waitForSelector('ytd-thumbnail.ytd-video-renderer');
        await page.screenshot({path: 'youtube_search_list.png'});
        const videos = await page.$$('ytd-thumbnail.ytd-video-renderer');
        await videos[0].click();
        await page.waitForSelector('.html5-video-container');
        await page.waitFor(5000);
        await page.screenshot({ path: 'youtube_search_first.png' });
        await browser.close();
    })()
} catch (err) {
    console.error(err);
}

실제 결과로 나온 스크린샷입니다.

5

6

마치며

구글에 Puppeteer를 검색해보면, 개발자들이 다양하게 활용하고 있는 예제를 볼 수 있습니다. (예를 들면 챗봇)
사용법도 쉽고, 예제도 많은 편이라 Puppeteer를 활용해 무엇을 해볼 지 고민해보면 좋을 거 같습니다. 저는 간단한 구글확장프로그램을 만들어보려합니다. 다음 글은 아마 Puppeteer를 활용한 스크린샷 구글확장프로그램 만들기가 될 듯합니다. :)