puppeteer-automation
mindrally/skills
Puppeteer를 활용한 브라우저 자동화에 대한 전문가의 지침으로, 헤드리스 크롬 환경에서 웹 스크래핑, 테스트, 스크린샷 캡처 및 자바스크립트 실행을 위한 모범 사례를 다룹니다.
...모든 것을 확장하십시오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 기본 인증, 쿠키 설정, 읽기 및 삭제 기능을 지원합니다.
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
- Always close browser instances in finally blocks
- Use
waitForSelectorbefore interacting with elements - Prefer
networkidle2overnetworkidle0for faster loads - Use stealth plugin for anti-bot bypass
- Implement proper error handling and retries
- Monitor memory usage in long-running scripts
- Use browser context for isolated sessions
- Set reasonable timeouts for all operations
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
복사





집
