본문으로 건너뛰기
Previous
Next
Puppeteer 완벽 가이드 | 웹 스크래핑·자동화·PDF 생성·테스트·실전 활용

Puppeteer 완벽 가이드 | 웹 스크래핑·자동화·PDF 생성·테스트·실전 활용

Puppeteer 완벽 가이드 | 웹 스크래핑·자동화·PDF 생성·테스트·실전 활용

이 글의 핵심

Puppeteer로 웹 자동화를 구현하는 완벽 가이드. 스크래핑, 스크린샷, PDF 생성, 폼 자동화, 테스트까지 실전 예제로 정리. Puppeteer·Web Scraping·Automation 중심으로 설명합니다. Start now.

이 글의 핵심

Puppeteer로 웹 자동화를 구현하는 완벽 가이드입니다. 스크래핑, 스크린샷, PDF 생성, 폼 자동화, 테스트까지 실전 예제로 정리했습니다.

실무 경험 공유: 수동 데이터 수집을 Puppeteer로 자동화하면서, 작업 시간이 10시간에서 10분으로 단축된 경험을 공유합니다.

들어가며: “수동 작업이 많아요”

실무 문제 시나리오

시나리오 1: 데이터 수집이 번거로워요

수동 복사는 느립니다. Puppeteer로 자동화할 수 있습니다. 시나리오 2: PDF 생성이 필요해요

라이브러리는 제한적입니다. Puppeteer로 완벽한 PDF를 생성할 수 있습니다. 시나리오 3: E2E 테스트가 필요해요

수동 테스트는 비효율적입니다. Puppeteer로 자동화할 수 있습니다.

1. Puppeteer란?

Chrome DevTools Protocol의 고수준 래퍼 (2017~)

Puppeteer2017년 Google Chrome 팀이 공개한 Node.js 라이브러리입니다. 브라우저 자동화 도구의 역사는 Selenium(2004)부터 시작되지만, Selenium은 WebDriver API(W3C 표준)를 통해 브라우저를 제어하므로 추가 드라이버(chromedriver, geckodriver)가 필요했습니다.

Puppeteer의 차별점:

  • Chrome DevTools Protocol(CDP)을 직접 사용 → 드라이버 불필요
  • Headless Chrome 내장npm install puppeteer 하나로 Chrome까지 설치
  • Chrome 팀 공식 → Chrome 신기능을 가장 빠르게 지원

CDP(Chrome DevTools Protocol)란?

CDP는 브라우저와 외부 도구가 통신하는 프로토콜입니다. Chrome DevTools(F12)도 이 프로토콜로 브라우저와 통신합니다.

Puppeteer (Node.js) 
    ↓ WebSocket (CDP)
Chrome Browser
    ↓ 렌더링·JS 실행
웹 페이지

Puppeteer가 할 수 있는 것 = DevTools가 할 수 있는 것:

  • DOM 조작·쿼리
  • 네트워크 요청 가로채기 (Request interception)
  • CPU·메모리 프로파일링
  • 커버리지 측정
  • 모바일 에뮬레이션

Puppeteer vs Playwright vs Selenium

측면PuppeteerPlaywrightSelenium
개발사GoogleMicrosoft오픈소스
출시201720202004
프로토콜CDPCDP + WebKitWebDriver
브라우저Chrome·ChromiumChrome·Firefox·Safari모든 브라우저
API 스타일Promise 기반Promise + Async ContextCallback·Promise
자동 대기부분적✅ 강력❌ 수동
병렬 테스트수동 구현✅ 내장수동 구현
사용 사례Chrome 전용 자동화크로스 브라우저 E2E레거시 브라우저 지원

선택 기준:

  • Chrome만 지원해도 됨 → Puppeteer (가볍고 빠름)
  • 크로스 브라우저 필요 → Playwright (Firefox·Safari까지)
  • IE11 지원 필요 → Selenium (레거시)

핵심 특징

Puppeteer는 Headless Chrome 제어 라이브러리입니다. 주요 기능:

  • 웹 스크래핑: 데이터 수집 (동적 콘텐츠·인증 포함)
  • 스크린샷: 페이지 캡처 (전체 페이지·viewport·특정 요소)
  • PDF 생성: 웹 페이지를 PDF로 (CSS 레이아웃 완벽 재현)
  • 폼 자동화: 자동 입력·제출 (반복 작업 제거)
  • E2E 테스트: 자동화 테스트 (사용자 시나리오 검증)
  • 성능 분석: Network·CPU·Memory 프로파일링

2. 설치 및 기본 사용

설치

npm install puppeteer

기본 예제

import puppeteer from 'puppeteer';
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  const title = await page.title();
  console.log('Title:', title);
  await browser.close();
})();

3. 스크래핑

텍스트 추출

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com');
const titles = await page.$$eval('.titleline > a', (elements) =>
  elements.map((el) => el.textContent)
);
console.log(titles);
await browser.close();

복잡한 스크래핑

const products = await page.$$eval('.product', (elements) =>
  elements.map((el) => ({
    name: el.querySelector('.name')?.textContent,
    price: el.querySelector('.price')?.textContent,
    image: el.querySelector('img')?.src,
  }))
);
console.log(products);

4. 스크린샷

전체 페이지

// 실행 예제
await page.goto('https://example.com');
await page.screenshot({
  path: 'screenshot.png',
  fullPage: true,
});

특정 요소

const element = await page.$('.header');
await element?.screenshot({ path: 'header.png' });

5. PDF 생성

await page.goto('https://example.com', {
  waitUntil: 'networkidle0',
});
await page.pdf({
  path: 'page.pdf',
  format: 'A4',
  printBackground: true,
  margin: {
    top: '20px',
    right: '20px',
    bottom: '20px',
    left: '20px',
  },
});

6. 폼 자동화

로그인

await page.goto('https://example.com/login');
await page.type('#email', '[email protected]');
await page.type('#password', 'password123');
await page.click('button[type="submit"]');
await page.waitForNavigation();
console.log('Logged in!');

파일 업로드

const fileInput = await page.$('input[type="file"]');
await fileInput?.uploadFile('./file.pdf');

7. 대기

waitForSelector

await page.waitForSelector('.content', {
  visible: true,
  timeout: 5000,
});

waitForNavigation

await Promise.all([
  page.waitForNavigation(),
  page.click('a.link'),
]);

커스텀 대기

await page.waitForFunction(
  () => document.querySelector('.data')?.textContent?.length > 0
);

8. 실전 예제: 뉴스 스크래핑

import puppeteer from 'puppeteer';
import fs from 'fs/promises';
async function scrapeNews() {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com');
  const articles = await page.$$eval('.athing', (elements) =>
    elements.slice(0, 10).map((el) => {
      const titleEl = el.querySelector('.titleline > a');
      const scoreEl = el.nextElementSibling?.querySelector('.score');
      return {
        title: titleEl?.textContent || ',
        url: titleEl?.href || ',
        score: scoreEl?.textContent || '0',
      };
    })
  );
  await fs.writeFile('news.json', JSON.stringify(articles, null, 2));
  console.log(`Scraped ${articles.length} articles`);
  await browser.close();
}
scrapeNews();

정리 및 체크리스트

핵심 요약

  • Puppeteer: Headless Chrome 제어
  • 웹 스크래핑: 데이터 수집
  • 스크린샷: 페이지 캡처
  • PDF 생성: 웹을 PDF로
  • 폼 자동화: 자동 입력
  • E2E 테스트: 자동화

구현 체크리스트

  • Puppeteer 설치
  • 브라우저 실행
  • 페이지 이동
  • 스크래핑 구현
  • 스크린샷 생성
  • PDF 생성
  • 폼 자동화

같이 보면 좋은 글


이 글에서 다루는 키워드

Puppeteer, Web Scraping, Automation, PDF, Testing, Node.js, Chrome

내부 동작과 핵심 메커니즘

이 글의 주제는 「Puppeteer 완벽 가이드 | 웹 스크래핑·자동화·PDF 생성·테스트·실전 활용」입니다. 여기서는 앞선 설명을 구현·런타임 관점에서 한 번 더 압축합니다. 요청 경로와 상태 전이를 기준으로 생각하면, “입력이 어디서 검증되고, 핵심 연산이 어디서 일어나며, 부작용(I/O·네트워크·디스크)이 어디서 터지는가”가 한눈에 드러납니다.

처리 파이프라인(개념도)

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]

알고리즘·프로토콜 관점에서의 체크포인트

  • 불변 조건(Invariant): 각 단계가 만족해야 하는 조건(예: 버퍼 경계, 프로토콜 상태, 트랜잭션 격리)을 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 동일 입력에 동일 출력이 보장되는 순수한 층과, 시간·네트워크에 의해 달라질 수 있는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화/역직렬화, 문자 인코딩, syscall 횟수, 락 경합처럼 “한 번의 호출이 아니라 누적되는 비용”을 의심 목록에 넣습니다.

프로덕션 운영 패턴

실서비스에서는 기능 구현과 함께 관측·배포·보안·비용이 동시에 요구됩니다. 아래는 팀에서 자주 쓰는 최소 체크리스트입니다.

영역운영 관점에서의 질문
관측성요청 단위 상관 ID, 에러율/지연 분위수, 주요 의존성 타임아웃이 보이는가
안전성입력 검증·권한·비밀 관리가 코드 경로마다 일관적인가
신뢰성재시도는 멱등한 연산에만 적용되는가, 서킷 브레이커·백오프가 있는가
성능캐시 계층·배치 크기·풀링·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리, 마이그레이션 호환성이 문서화되어 있는가

운영 환경에서는 “개발자 PC에서는 재현되지 않던 문제”가 시간·부하·데이터 크기 때문에 드러납니다. 따라서 스테이징의 데이터 양·네트워크 지연을 가능한 한 현실에 가깝게 맞추는 것이 중요합니다.


문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스 컨디션, 타임아웃, 외부 의존성 불안정최소 재현 스크립트 작성, 분산 트레이스·로그 상관관계 확인
성능 저하N+1 쿼리, 동기 I/O, 잠금 경합, 과도한 직렬화프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 클로저/이벤트 구독 누수, 대용량 객체의 불필요한 복사상한·TTL·스냅샷 비교(힙 덤프/트레이스)
빌드·배포만 실패환경 변수·권한·플랫폼 차이CI 로그와 로컬 diff, 컨테이너/런타임 버전 핀(pin)

권장 디버깅 순서: (1) 최소 재현 만들기 (2) 최근 변경 범위 좁히기 (3) 의존성·환경 변수 차이 확인 (4) 관측 데이터로 가설 검증 (5) 수정 후 회귀·부하 테스트.

자주 묻는 질문 (FAQ)

Q. Playwright와 비교하면 어떤가요?

A. Playwright가 더 빠르고 크로스 브라우저 지원이 좋습니다. Puppeteer는 Chrome에 특화되어 있습니다.

Q. 합법적인가요?

A. 스크래핑은 사이트의 robots.txt와 이용약관을 확인해야 합니다.

Q. Headless 모드가 뭔가요?

A. UI 없이 백그라운드에서 실행되는 모드입니다. 더 빠르고 서버에 적합합니다.

Q. 프로덕션에서 사용해도 되나요?

A. 네, Google에서 만든 안정적인 라이브러리입니다.