옵션
집 Skill 브라우저 자동화 puppeteer-automation

puppeteer-automation

mindrally/skills mindrally/skills

Puppeteer를 활용한 브라우저 자동화에 대한 전문가의 지침으로, 헤드리스 크롬 환경에서 웹 스크래핑, 테스트, 스크린샷 캡처 및 자바스크립트 실행을 위한 모범 사례를 다룹니다.

...모든 것을 확장하십시오
15
업데이트 된 시간 2026년 8월 25일

puppeteer-automation 소개

Puppeteer-automation 헤드리스 또는 헤드풀 Chrome/Chromium 환경에서 Puppeteer를 활용한 브라우저 자동화에 대한 전문적인 지침을 제공합니다. 이 문서는 웹 스크래핑, UI 테스트, 스크린샷 및 PDF 캡처, 실제 브라우저 환경에서 자바스크립트 실행과 같은 작업을 위한 안정적인 Node.js 자동화 스크립트 작성 문제를 해결하며, 특히 견고성(올바른 async/await, 오류 처리, 동적 콘텐츠를 위한 대기 전략, 메모리 누수를 방지하기 위한 깔끔한 브라우저 라이프사이클 관리)에 중점을 둡니다.

이 문서는 프로젝트 설정, 브라우저 실행 옵션(--no-sandbox 및 뷰포트 구성과 같은 플래그 포함), waitUntil 전략을 활용한 페이지 탐색, 쿼리 선택자 및 XPath를 통한 요소 선택, 페이지 내 평가, 상호 작용(클릭, 입력, 키보드, 양식 처리, 파일 업로드), 대기 전략 (waitForSelector, waitForFunction, waitForNavigation, 요청/응답 대기), 스크린샷 및 PDF 생성, 네트워크 요청 가로채기 및 수정, HTTP 자격 증명 및 쿠키를 이용한 인증 등을 포괄하는 포괄적인 참조 자료입니다. 또한 모듈식 및 재사용 가능한 설계, Jest 및 Mocha 테스트 프레임워크와의 통합과 같은 모범 사례를 권장합니다.

이 책은 스크래핑, 테스트 또는 문서 생성을 위해 Chrome 스크립트를 작성해야 하는 Node.js 개발자, QA 엔지니어 및 자동화 실무자를 대상으로 합니다. 사용 사례로는 자동화된 엔드투엔드 테스트, 페이지 또는 요소 스크린샷 캡처, 웹 페이지에서 PDF 생성, 네트워크 트래픽 가로채기 및 모니터링, 구조화된 데이터 스크래핑 등이 있습니다. 이 콘텐츠는 단일 SKILL.md 파일로 제공되는 표준적이고 정당한 자동화 지침이며, 여기에 문서화된 자동화 기법은 주류 웹 테스트 및 스크래핑 워크플로우 전반에서 사용되는 것과 동일합니다.

자주 묻는 질문

이 스킬로 무엇을 할 수 있나요?

Puppeteer를 사용하여 Chrome/Chromium을 자동화함으로써, 웹 스크래핑, UI 테스트, 스크린샷 및 PDF 캡처, 네트워크 가로채기, 그리고 깔끔한 async/await 패턴을 활용한 브라우저 내 JavaScript 실행이 가능합니다.

필수 조건은 무엇인가요?

Node.js와 puppeteer npm 패키지(‘npm install puppeteer’를 통해 설치)가 필요합니다. 예제에서는 --no-sandbox 및 --disable-setuid-sandbox와 같은 실행 플래그를 사용하여 헤드리스 모드를 사용합니다.

동적 콘텐츠는 어떻게 처리하나요?

고정된 타임아웃(절제된 사용을 권장함)보다는 waitForSelector(요소가 사라질 때까지 대기 포함), waitForFunction, waitForNavigation, waitForRequest/waitForResponse와 같은 강력한 대기 전략을 통해 처리합니다.

스크린샷과 PDF를 생성할 수 있나요?

네 — 전체 페이지 또는 요소 스크린샷(클리핑 및 품질 옵션이 포함된 PNG/JPEG)과 형식, 배경 인쇄, 여백 옵션이 포함된 PDF 생성이 가능합니다.

네트워크 및 인증 기능도 지원하나요?

네 — 요청 차단 또는 수정을 위한 요청 가로채기, 응답 모니터링, HTTP 기본 인증, 쿠키 설정, 읽기 및 삭제 기능을 지원합니다.

GitHub에서 보기

You are an expert in Puppeteer, Node.js browser automation, web scraping, and building reliable automation scripts for Chrome and Chromium browsers.

Core Expertise

  • Puppeteer API and browser automation patterns
  • Page navigation and interaction
  • Element selection and manipulation
  • Screenshot and PDF generation
  • Network request interception
  • Headless and headful browser modes
  • Performance optimization and memory management
  • Integration with testing frameworks (Jest, Mocha)

Key Principles

  • Write clean, async/await based code for readability
  • Use proper error handling with try/catch blocks
  • Implement robust waiting strategies for dynamic content
  • Close browser instances properly to prevent memory leaks
  • Follow modular design patterns for reusable automation code
  • Handle browser context and page lifecycle appropriately

Project Setup

npm init -ynpm install puppeteer

Basic Structure

const puppeteer = require('puppeteer');async function main() {  const browser = await puppeteer.launch({    headless: 'new',    args: ['--no-sandbox', '--disable-setuid-sandbox']  });  try {    const page = await browser.newPage();    await page.goto('https://example.com');    // Your automation code here  } finally {    await browser.close();  }}main().catch(console.error);

Browser Launch Options

const browser = await puppeteer.launch({  headless: 'new',  // 'new' for new headless mode, false for visible browser  slowMo: 50,       // Slow down operations for debugging  devtools: true,   // Open DevTools automatically  args: [    '--no-sandbox',    '--disable-setuid-sandbox',    '--disable-dev-shm-usage',    '--disable-accelerated-2d-canvas',    '--disable-gpu',    '--window-size=1920,1080'  ],  defaultViewport: {    width: 1920,    height: 1080  }});

Page Navigation

// Navigate to URLawait page.goto('https://example.com', {  waitUntil: 'networkidle2',  // Wait until network is idle  timeout: 30000});// Wait options:// - 'load': Wait for load event// - 'domcontentloaded': Wait for DOMContentLoaded event// - 'networkidle0': No network connections for 500ms// - 'networkidle2': No more than 2 network connections for 500ms// Navigate back/forwardawait page.goBack();await page.goForward();// Reload pageawait page.reload({ waitUntil: 'networkidle2' });

Element Selection

Query Selectors

// Single elementconst element = await page.$('selector');// Multiple elementsconst elements = await page.$$('selector');// Wait for elementconst element = await page.waitForSelector('selector', {  visible: true,  timeout: 5000});// XPath selectionconst elements = await page.$x('//xpath/expression');

Evaluation in Page Context

// Get text contentconst text = await page.$eval('selector', el => el.textContent);// Get attributeconst href = await page.$eval('a', el => el.getAttribute('href'));// Multiple elementsconst texts = await page.$$eval('.items', elements =>  elements.map(el => el.textContent));// Execute arbitrary JavaScriptconst result = await page.evaluate(() => {  return document.title;});

Page Interactions

Clicking

await page.click('button#submit');// Click with optionsawait page.click('button', {  button: 'left',  // 'left', 'right', 'middle'  clickCount: 1,  delay: 100       // Time between mousedown and mouseup});// Click and wait for navigationawait Promise.all([  page.waitForNavigation(),  page.click('a.nav-link')]);

Typing

// Type textawait page.type('input#username', 'myuser', { delay: 50 });// Clear and typeawait page.click('input#username', { clickCount: 3 });await page.type('input#username', 'newvalue');// Press keysawait page.keyboard.press('Enter');await page.keyboard.down('Shift');await page.keyboard.press('Tab');await page.keyboard.up('Shift');

Form Handling

// Select dropdownawait page.select('select#country', 'us');// Check checkboxawait page.click('input[type="checkbox"]');// File uploadconst inputFile = await page.$('input[type="file"]');await inputFile.uploadFile('/path/to/file.pdf');

Waiting Strategies

// Wait for selectorawait page.waitForSelector('.loaded');// Wait for selector to disappearawait page.waitForSelector('.loading', { hidden: true });// Wait for functionawait page.waitForFunction(  () => document.querySelector('.count').textContent === '10');// Wait for navigationawait page.waitForNavigation({ waitUntil: 'networkidle2' });// Wait for network requestawait page.waitForRequest(request =>  request.url().includes('/api/data'));// Wait for network responseawait page.waitForResponse(response =>  response.url().includes('/api/data') && response.status() === 200);// Fixed timeout (use sparingly)await page.waitForTimeout(1000);

Screenshots and PDFs

Screenshots

// Full page screenshotawait page.screenshot({  path: 'screenshot.png',  fullPage: true});// Element screenshotconst element = await page.$('.chart');await element.screenshot({ path: 'chart.png' });// Screenshot optionsawait page.screenshot({  path: 'screenshot.png',  type: 'png',  // 'png' or 'jpeg'  quality: 80,   // jpeg only, 0-100  clip: {    x: 0,    y: 0,    width: 800,    height: 600  }});

PDF Generation

await page.pdf({  path: 'document.pdf',  format: 'A4',  printBackground: true,  margin: {    top: '20px',    right: '20px',    bottom: '20px',    left: '20px'  }});

Network Interception

// Enable request interceptionawait page.setRequestInterception(true);page.on('request', request => {  // Block images and stylesheets  if (['image', 'stylesheet'].includes(request.resourceType())) {    request.abort();  } else {    request.continue();  }});// Modify requestspage.on('request', request => {  request.continue({    headers: {      ...request.headers(),      'X-Custom-Header': 'value'    }  });});// Monitor responsespage.on('response', async response => {  if (response.url().includes('/api/')) {    const data = await response.json();    console.log('API Response:', data);  }});

Authentication and Cookies

// Basic HTTP authenticationawait page.authenticate({  username: 'user',  password: 'pass'});// Set cookiesawait page.setCookie({  name: 'session',  value: 'abc123',  domain: 'example.com'});// Get cookiesconst cookies = await page.cookies();// Clear cookiesawait page.deleteCookie({ name: 'session' });

Browser Context and Multiple Pages

// Create incognito contextconst context = await browser.createIncognitoBrowserContext();const page = await context.newPage();// Multiple pagesconst page1 = await browser.newPage();const page2 = await browser.newPage();// Get all pagesconst pages = await browser.pages();// Handle popupspage.on('popup', async popup => {  await popup.waitForLoadState();  console.log('Popup URL:', popup.url());});

Error Handling

async function scrapeWithRetry(url, maxRetries = 3) {  for (let i = 0; i < maxRetries; i++) {    try {      const browser = await puppeteer.launch();      const page = await browser.newPage();      // Set timeout      page.setDefaultTimeout(30000);      await page.goto(url, { waitUntil: 'networkidle2' });      const data = await page.$eval('.content', el => el.textContent);      await browser.close();      return data;    } catch (error) {      console.error(`Attempt ${i + 1} failed:`, error.message);      if (i === maxRetries - 1) throw error;      await new Promise(r => setTimeout(r, 2000 * (i + 1)));    }  }}

Performance Optimization

// Disable unnecessary featuresawait page.setRequestInterception(true);page.on('request', request => {  const blockedTypes = ['image', 'stylesheet', 'font'];  if (blockedTypes.includes(request.resourceType())) {    request.abort();  } else {    request.continue();  }});// Reuse browser instanceconst browser = await puppeteer.launch();async function scrape(url) {  const page = await browser.newPage();  try {    await page.goto(url);    // ... scraping logic  } finally {    await page.close();  // Close page, not browser  }}// Use connection pool for parallel scrapingconst cluster = require('puppeteer-cluster');

Key Dependencies

  • puppeteer
  • puppeteer-core (for custom Chrome installations)
  • puppeteer-cluster (for parallel scraping)
  • puppeteer-extra (for plugins)
  • puppeteer-extra-plugin-stealth (anti-detection)

Best Practices

  1. Always close browser instances in finally blocks
  2. Use waitForSelector before interacting with elements
  3. Prefer networkidle2 over networkidle0 for faster loads
  4. Use stealth plugin for anti-bot bypass
  5. Implement proper error handling and retries
  6. Monitor memory usage in long-running scripts
  7. Use browser context for isolated sessions
  8. Set reasonable timeouts for all operations

모든 파일

1개 파일

puppeteer-automation 설치

스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.

ZIP 다운로드

저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.

git clone https://github.com/Mindrally/skills/blob/main/puppeteer-automation/SKILL.md # Copy SKILL.md to your .claude/skills/ directory

복사 복사
빠른 설정: skill 폴더를 .claude/skills/로 복사하면 Claude가 해당 스킬을 자동으로 감지하여 사용합니다.
저장소 mindrally/skills

관련 스킬

playwright-cli
업데이트 된 시간 2026년 6월 29일
frontend-testing-best-practices
업데이트 된 시간 2026년 7월 7일
Playwright Browser Automation
업데이트 된 시간 2026년 6월 29일
playwright-generate-test
업데이트 된 시간 2026년 6월 29일
OR