Menu
Nazad na Blog
1 min read
Automatisierung

Puppeteer: Browser Automation mit Chrome DevTools Protocol

Puppeteer für Browser Automation. Chrome DevTools Protocol, Headless Mode, Screenshots, PDF Generation und Testing.

PuppeteerBrowser AutomationChrome DevTools ProtocolHeadless ChromeScreenshotPDF
Puppeteer: Browser Automation mit Chrome DevTools Protocol

Puppeteer: Browser Automation mit Chrome DevTools Protocol

Meta-Description: Puppeteer für Browser Automation. Chrome DevTools Protocol, Headless Mode, Screenshots, PDF Generation und Testing.

Keywords: Puppeteer, Browser Automation, Chrome DevTools Protocol, Headless Chrome, Screenshot, PDF, Web Testing


Einführung

Puppeteer ist die offizielle Node.js Library von Google für Chrome/Firefox Automation. Über das Chrome DevTools Protocol (CDP) bietet es direkten Zugang zu Browser-Funktionen, die über normale APIs nicht erreichbar sind.


2026 Updates

┌─────────────────────────────────────────────────────────────┐
│              PUPPETEER 2026                                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Neue Features:                                             │
│  ├── WebDriver BiDi Protocol Support                       │
│  ├── Firefox vollständig unterstützt                       │
│  ├── Neuer Headless Mode (schwerer zu detecten)            │
│  ├── Verbesserte Locator API                               │
│  └── 15-20% weniger Memory Usage                           │
│                                                             │
│  DevTools Protocol:                                         │
│  ├── Network Interception                                  │
│  ├── Performance Metrics                                   │
│  ├── Coverage Reports                                      │
│  ├── Console Logs                                          │
│  └── Security/Certificate Handling                         │
│                                                             │
│  Use Cases:                                                 │
│  ├── Web Scraping                                          │
│  ├── Automated Testing                                     │
│  ├── PDF Generation                                        │
│  ├── Screenshot Services                                   │
│  └── Performance Auditing                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Setup

# Mit Chrome Download
npm install puppeteer

# Ohne Chrome (für eigene Installation)
npm install puppeteer-core
// basic.ts
import puppeteer from 'puppeteer';

async function main() {
  const browser = await puppeteer.launch({
    headless: true,  // 'new' Headless Mode ist default
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage'
    ]
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });

  await page.goto('https://example.com');

  const title = await page.title();
  console.log('Title:', title);

  await browser.close();
}

Screenshots & PDFs

// Screenshot
async function captureScreenshot(url: string, outputPath: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.setViewport({ width: 1920, height: 1080 });
  await page.goto(url, { waitUntil: 'networkidle0' });

  // Full Page Screenshot
  await page.screenshot({
    path: outputPath,
    fullPage: true,
    type: 'png'
  });

  // Specific Element
  const element = await page.$('.hero-section');
  if (element) {
    await element.screenshot({ path: 'hero.png' });
  }

  // Mit Clip (Ausschnitt)
  await page.screenshot({
    path: 'clip.png',
    clip: {
      x: 0,
      y: 0,
      width: 800,
      height: 600
    }
  });

  await browser.close();
}

// PDF Generation
async function generatePDF(url: string, outputPath: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto(url, { waitUntil: 'networkidle0' });

  // Print-Styles laden
  await page.emulateMediaType('print');

  await page.pdf({
    path: outputPath,
    format: 'A4',
    printBackground: true,
    margin: {
      top: '20mm',
      right: '20mm',
      bottom: '20mm',
      left: '20mm'
    },
    displayHeaderFooter: true,
    headerTemplate: '<div style="font-size:10px; text-align:center; width:100%;">Header</div>',
    footerTemplate: '<div style="font-size:10px; text-align:center; width:100%;"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'
  });

  await browser.close();
}

// Invoice PDF aus HTML
async function generateInvoicePDF(html: string): Promise<Buffer> {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.setContent(html, { waitUntil: 'networkidle0' });

  const pdf = await page.pdf({
    format: 'A4',
    printBackground: true
  });

  await browser.close();
  return pdf;
}

Form Handling & Interaction

async function fillAndSubmitForm(page: Page) {
  // Text Input
  await page.type('#email', 'user@example.com', { delay: 50 });
  await page.type('#password', 'secretpassword', { delay: 50 });

  // Checkbox
  await page.click('#terms');

  // Select Dropdown
  await page.select('#country', 'DE');

  // Radio Button
  await page.click('input[name="plan"][value="premium"]');

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

  // Submit
  await Promise.all([
    page.waitForNavigation(),
    page.click('button[type="submit"]')
  ]);
}

// Keyboard & Mouse
async function advancedInteraction(page: Page) {
  // Keyboard
  await page.keyboard.press('Tab');
  await page.keyboard.type('Hello World');
  await page.keyboard.down('Shift');
  await page.keyboard.press('ArrowLeft');
  await page.keyboard.up('Shift');
  await page.keyboard.press('Backspace');

  // Mouse
  await page.mouse.move(100, 200);
  await page.mouse.click(100, 200);
  await page.mouse.wheel({ deltaY: 500 });

  // Drag & Drop
  const source = await page.$('#drag-source');
  const target = await page.$('#drop-target');

  if (source && target) {
    const sourceBox = await source.boundingBox();
    const targetBox = await target.boundingBox();

    if (sourceBox && targetBox) {
      await page.mouse.move(
        sourceBox.x + sourceBox.width / 2,
        sourceBox.y + sourceBox.height / 2
      );
      await page.mouse.down();
      await page.mouse.move(
        targetBox.x + targetBox.width / 2,
        targetBox.y + targetBox.height / 2
      );
      await page.mouse.up();
    }
  }
}

Network Interception

import { Page, HTTPRequest } from 'puppeteer';

async function interceptNetwork(page: Page) {
  await page.setRequestInterception(true);

  page.on('request', (request: HTTPRequest) => {
    const resourceType = request.resourceType();
    const url = request.url();

    // Block Images, CSS, Fonts
    if (['image', 'stylesheet', 'font'].includes(resourceType)) {
      request.abort();
      return;
    }

    // Block Tracking
    if (url.includes('analytics') || url.includes('tracking')) {
      request.abort();
      return;
    }

    // Modify Headers
    const headers = {
      ...request.headers(),
      'X-Custom-Header': 'value'
    };

    request.continue({ headers });
  });

  // Response Interception
  page.on('response', async (response) => {
    if (response.url().includes('/api/')) {
      try {
        const json = await response.json();
        console.log('API Response:', json);
      } catch {}
    }
  });
}

// Mock API Responses
async function mockApi(page: Page) {
  await page.setRequestInterception(true);

  page.on('request', (request) => {
    if (request.url().includes('/api/users')) {
      request.respond({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify([
          { id: 1, name: 'Mock User' }
        ])
      });
    } else {
      request.continue();
    }
  });
}

Chrome DevTools Protocol Direct Access

async function cdpAccess(page: Page) {
  const client = await page.target().createCDPSession();

  // Network Conditions (Throttling)
  await client.send('Network.emulateNetworkConditions', {
    offline: false,
    downloadThroughput: 1.5 * 1024 * 1024 / 8,  // 1.5 Mbps
    uploadThroughput: 750 * 1024 / 8,            // 750 Kbps
    latency: 40                                   // 40ms
  });

  // CPU Throttling
  await client.send('Emulation.setCPUThrottlingRate', { rate: 4 });

  // Performance Metrics
  await client.send('Performance.enable');
  const metrics = await client.send('Performance.getMetrics');
  console.log('Performance Metrics:', metrics);

  // Coverage (CSS/JS Usage)
  await client.send('CSS.startRuleUsageTracking');
  // ... navigate and interact
  const coverage = await client.send('CSS.stopRuleUsageTracking');
  console.log('CSS Coverage:', coverage);

  // Clear Browser Data
  await client.send('Network.clearBrowserCache');
  await client.send('Network.clearBrowserCookies');

  // Console Messages
  client.on('Runtime.consoleAPICalled', (event) => {
    console.log('Console:', event.type, event.args);
  });
}

Performance Testing

async function measurePerformance(url: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Performance Observer
  await page.evaluateOnNewDocument(() => {
    window.performanceEntries = [];

    const observer = new PerformanceObserver((list) => {
      window.performanceEntries.push(...list.getEntries());
    });

    observer.observe({ entryTypes: ['navigation', 'resource', 'paint', 'largest-contentful-paint'] });
  });

  await page.goto(url, { waitUntil: 'networkidle0' });

  // Metrics abrufen
  const metrics = await page.metrics();
  console.log('Puppeteer Metrics:', {
    JSHeapUsedSize: metrics.JSHeapUsedSize,
    LayoutCount: metrics.LayoutCount,
    RecalcStyleCount: metrics.RecalcStyleCount
  });

  // Performance Timing
  const timing = await page.evaluate(() => {
    const t = performance.timing;
    return {
      dns: t.domainLookupEnd - t.domainLookupStart,
      tcp: t.connectEnd - t.connectStart,
      ttfb: t.responseStart - t.requestStart,
      download: t.responseEnd - t.responseStart,
      domInteractive: t.domInteractive - t.navigationStart,
      domComplete: t.domComplete - t.navigationStart,
      load: t.loadEventEnd - t.navigationStart
    };
  });

  console.log('Timing:', timing);

  // Core Web Vitals
  const cwv = await page.evaluate(() => {
    return (window as any).performanceEntries.filter(
      e => ['largest-contentful-paint', 'first-input', 'layout-shift'].includes(e.entryType)
    );
  });

  await browser.close();
  return { metrics, timing, cwv };
}

Stealth Mode

import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';

puppeteer.use(StealthPlugin());

async function stealthBrowse() {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--disable-blink-features=AutomationControlled',
      '--no-sandbox'
    ]
  });

  const page = await browser.newPage();

  // Additional Stealth
  await page.evaluateOnNewDocument(() => {
    // Chrome Runtime
    Object.defineProperty(navigator, 'webdriver', {
      get: () => false
    });

    // Permissions
    const originalQuery = window.navigator.permissions.query;
    window.navigator.permissions.query = (parameters: any) =>
      parameters.name === 'notifications'
        ? Promise.resolve({ state: 'denied' } as PermissionStatus)
        : originalQuery(parameters);

    // Plugins
    Object.defineProperty(navigator, 'plugins', {
      get: () => [1, 2, 3, 4, 5]
    });
  });

  await page.goto('https://bot.sannysoft.com');
  await page.screenshot({ path: 'stealth-test.png', fullPage: true });

  await browser.close();
}

Fazit

Puppeteer 2026 bietet:

  1. CDP Direct Access: Volle Browser-Kontrolle
  2. Multi-Browser: Chrome + Firefox (WebDriver BiDi)
  3. New Headless: Schwerer zu detecten
  4. Performance Tools: Metrics, Coverage, Auditing

Ideal für Testing, PDF-Generation und Chrome-spezifische Features.


Bildprompts

  1. "Puppet master controlling browser strings, automation concept"
  2. "Chrome DevTools with code connections, developer tools visualization"
  3. "PDF documents being generated from web pages, document automation"

Quellen