PREISE
USE CASES
LÖSUNGEN
nach Anwendungsfällen
AI Lead ManagementFakturierungSoziale MedienProjektmanagementDatenmanagementnach Branche
MEHR ERFAHREN
BlogTemplateVideosYoutubeRESSOURCEN
COMMUNITYS UND SOZIALE MEDIEN
PARTNER
Fehlerbeseitigung Puppenspieler Skripte können überwältigend sein, aber das Beherrschen einiger wichtiger Techniken kann Ihnen Zeit und Frust ersparen. Hier ist ein kurzer Überblick über das, was Sie lernen werden:
slowMo
Modus und Headful-Browsermodus, um Ihr Skript in Aktion zu sehen.try-catch
Blöcke und automatisieren Sie Fehler-Screenshots für eine bessere Fehlerbehebung.const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true
});
DEBUG="puppeteer:*"
für detaillierte Protokolle.Durch die Kombination dieser Techniken optimieren Sie Ihren Debugging-Prozess und verbessern die Zuverlässigkeit Ihrer Puppeteer-Skripte.
Richten Sie Puppeteer mit diesen Startoptionen zum Debuggen ein:
const browser = await puppeteer.launch({
headless: false,
slowMo: 20,
devtools: true
});
Um eine detaillierte Protokollierung zu aktivieren, führen Sie Ihr Skript mit dem folgenden Befehl aus:
DEBUG="puppeteer:*" node script.js
Verwenden Sie nach der Konfiguration Debugging-Tools, um das Verhalten Ihres Skripts zu analysieren und zu verfeinern.
Hier sind einige Tools, die Ihnen dabei helfen, Probleme effektiv zu lösen:
Werkzeug | Sinn | Hauptmerkmal |
---|---|---|
Chrome DevTools | Skripte prüfen | Konsolen- und Netzwerktools |
VS-Code Debugger | Haltepunkte verwalten | Schrittweise Ausführung |
Screenshot-Dienstprogramm | Visuelle Fehlerbehebung | Seitenzustände erfassen |
Sie können Ihrem Code zur besseren Sichtbarkeit auch Prüfpunkte hinzufügen:
await page.screenshot({ path: 'before_click.png' });
await page.click('#button');
await page.screenshot({ path: 'after_click.png' });
Eine gute Organisation ist genauso wichtig wie die verwendeten Tools. Teilen Sie Ihr Skript in logische Module auf und integrieren Sie eine Fehlerbehandlung für ein reibungsloseres Debugging:
try {
await page.waitForSelector('#target-element');
await page.click('#target-element');
} catch (error) {
console.error(`Navigation failed: ${error.message}`);
await page.screenshot({ path: 'error-state.png' });
}
Um die Wahrscheinlichkeit einer Bot-Erkennung zu verringern, integrieren Sie das Stealth-Plugin:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
Stellen Sie abschließend eine ordnungsgemäße Ressourcenverwaltung sicher, indem Sie Bereinigungsverfahren implementieren:
async function cleanup() {
if (page) await page.close();
if (browser) await browser.close();
}
Dieses Setup bietet eine solide Grundlage für das visuelle und Konsolen-Debugging in Ihren Projekten.
Das Beobachten Ihrer Skripte in Aktion kann Probleme aufdecken, die bei herkömmlicher Codeanalyse möglicherweise übersehen werden. Diese Methoden erweitern Ihre Debugging-Optionen über Konsolenprotokolle und Fehlerverfolgung hinaus.
SlowMo führt eine Verzögerung zwischen den Aktionen des Puppeteers ein, sodass Sie leichter verfolgen können, was passiert:
const browser = await puppeteer.launch({
headless: false,
slowMo: 250,
devtools: true
});
Das slowMo
Der Wert (in Millisekunden) steuert die Verzögerung zwischen Aktionen. Passen Sie ihn je nach Test an:
Operationstyp | Empfohlene Zeitlupe (ms) | Luftüberwachung |
---|---|---|
Einfache Klicks | 100-250 | Grundlegende Navigationsschritte |
Formular ausfüllen | 250-500 | Testen der Eingabevalidierung |
Dynamischer Inhalt | 500-1000 | Ladezustände prüfen |
Nachdem Sie SlowMo eingerichtet haben, koppeln Sie es mit dem Browser-Ansichtsmodus, um zu überwachen, wie sich die Benutzeroberfläche während der Skriptausführung verhält.
Im Browser-Ansichtsmodus können Sie die Ausführung Ihres Skripts in einem sichtbaren Browserfenster sehen, was besonders beim Debuggen dynamischer Inhalte und komplexer Interaktionen hilfreich ist.
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1700, height: 800 },
args: ['--start-maximized']
});
Zum Beispiel Acme CorpDas QA-Team von nutzte diesen Modus im Juni 2024 zur Fehlerbehebung bei einem Web-Scraping-Skript. Es entdeckte fehlerhafte Selektoren und korrigierte diese, wodurch sich die Debugging-Zeit um 40 % verkürzte.
Ergänzend dazu können Sie Screenshots wichtiger visueller Zustände zur weiteren Analyse erstellen.
Screenshots und Videos können eine klare Aufzeichnung der Ausführung Ihres Skripts erstellen und so das Debuggen erleichtern:
// Screenshot of a specific element
await page.screenshot({
path: 'element-state.png',
clip: {
x: 0,
y: 0,
width: 500,
height: 300
}
});
// Full-page screenshot
await page.screenshot({
path: 'full-page.png',
fullPage: true
});
Aktivieren Sie zunächst den Browser-Ansichtsmodus, nutzen Sie SlowMo für detailliertes Tracking und dokumentieren Sie wichtige Momente mit Screenshots. Zusammen ergeben diese Schritte einen umfassenden visuellen Debugging-Prozess.
Konsolenmethoden bieten eine einfache Möglichkeit, textbasierte Einblicke in das Verhalten Ihrer Skripte zu erhalten. Diese Ausgaben arbeiten mit visuellem Debugging zusammen und liefern Ihnen präzise Details zur Skriptausführung.
Puppeteer erleichtert das Erfassen von Browsernachrichten mit Ereignishandlern wie diesen:
page.on('console', msg => {
console.log('PAGE LOG:', msg.text());
});
page.on('pageerror', err => {
console.error('PAGE ERROR:', err.message);
});
page.on('requestfailed', request => {
console.error('REQUEST FAILED:', request.url());
});
Dieses Setup erstellt ein Protokollierungssystem, das Konsolenmeldungen, Seitenfehler und fehlgeschlagene Anfragen erfasst. Zur besseren Übersichtlichkeit können Sie die Meldungen nach Typ kategorisieren:
Nachrichtentyp | Sinn | Beispielausgabe |
---|---|---|
Log | Allgemeine Hinweise | Standardausführungsablauf |
Fehler | Große Probleme | Fehlgeschlagene Operationen |
Warnung | Mögliche Bedenken | Leistungseinbußen |
Info | Status Updates | Aufgabe abgeschlossen |
Die richtigen console.log
Die sinnvolle Verwendung erleichtert das Debuggen erheblich. Platzieren Sie Protokolle strategisch, um den Fortschritt zu verfolgen und Probleme zu identifizieren:
// Log before attempting to find an element
console.log(`Looking for element: ${selector}`);
const element = await page.$(selector);
// Log after confirming the element exists
console.log(`Element found: ${!!element}`);
// Log form data before filling it out
console.log(`Form data: ${JSON.stringify(formData)}`);
await page.type('#email', formData.email);
Bei komplexeren Problemen können erweiterte Protokollierungstechniken entscheidende Vorteile bieten:
// Enable detailed debugging for Puppeteer
process.env.DEBUG = 'puppeteer:*';
process.env.DEBUG_MAX_STRING_LENGTH = null;
// Monitor pending protocol calls
const browser = await puppeteer.launch({
dumpio: true
});
console.log(browser.debugInfo.pendingProtocolErrors);
Ein Team konnte nach der Einführung einer detaillierten Protokollierung einen Rückgang der Testfehler um 40 % verzeichnen.
// Filter out specific network domain messages
// Command: DEBUG="puppeteer:*" DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'
Diese Methoden fügen Ihrem Debugging-Prozess eine textbasierte Ebene hinzu und helfen Ihnen, Probleme effektiver zu erkennen und zu lösen.
Das Debuggen komplexer Puppeteer-Skripte erfordert die Verwendung effektiver Fehlerbehandlungsstrategien und fortschrittlicher Techniken, um einen reibungslosen Ablauf der Skripte zu gewährleisten.
Wasser Try-Catch-Blöcke um Fehler effektiv zu verwalten und Ihr Skript am Laufen zu halten:
async function navigateAndScreenshot(url, selector) {
try {
await page.goto(url, { waitUntil: 'networkidle0' });
const element = await page.waitForSelector(selector, { timeout: 5000 });
await element.screenshot({ path: 'element.png' });
} catch (error) {
if (error instanceof TimeoutError) {
console.error(`Element ${selector} not found within timeout`);
// Add recovery logic if needed
await page.reload();
} else {
console.error(`Navigation failed: ${error.message}`);
throw error; // Re-throw unexpected errors
}
}
}
Sie können die Fehlerbehandlung verbessern, indem Sie Try-Catch-Blöcke mit benutzerdefinierten Fehlerklassen kombinieren, um eine bessere Kategorisierung und Reaktion zu erzielen.
Durch das Erstellen benutzerdefinierter Fehlerklassen können Sie Probleme effizienter lokalisieren und klassifizieren:
class PuppeteerScriptError extends Error {
constructor(message, details = {}) {
super(message);
this.name = 'PuppeteerScriptError';
this.details = details;
this.timestamp = new Date().toISOString();
}
}
class SelectorError extends PuppeteerScriptError {
constructor(selector, context) {
super(`Failed to find selector: ${selector}`, {
selector,
context,
type: 'SELECTOR_ERROR'
});
this.name = 'SelectorError';
}
}
Mit diesen Klassen können Sie asynchrone Vorgänge klarer verfolgen und debuggen.
Asynchroner Code führt häufig zu Zeitproblemen und uneingelösten Versprechen. Bewältigen Sie diese Probleme mit den folgenden Techniken:
// Enable detailed debugging for protocol calls
const browser = await puppeteer.launch({
dumpio: true
});
// Monitor unresolved promises periodically
setInterval(() => {
const pending = browser.debugInfo.pendingProtocolErrors;
if (pending.length > 0) {
console.log('Pending protocol calls:', pending);
}
}, 5000);
// Handle async errors with a timeout mechanism
async function safeExecute(promiseFn) {
try {
return await Promise.race([
promiseFn(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Operation timed out')), 30000)
)
]);
} catch (error) {
console.error(`Operation failed: ${error.message}`);
throw new PuppeteerScriptError('Execution timeout', {
originalError: error,
operation: promiseFn.name
});
}
}
Durch die Verwendung der debugInfo
Schnittstelle können Sie ausstehende Rückrufe überwachen und nicht eingelöste Versprechen während der Browserprotokollkommunikation identifizieren.
Debug-Ebene | Sinn | Umsetzung |
---|---|---|
Basic | Behandeln häufiger Fehler | Standardmäßige Try-Catch-Blöcke |
Aufbauend | Fehler klassifizieren | Benutzerdefinierte Fehlerklassenhierarchie |
Erweitert | Protokollprobleme verfolgen | Debug-Schnittstellenüberwachung |
In diesem Abschnitt werden häufige Probleme mit Puppeteer behandelt und klare Lösungen bereitgestellt, damit Ihre Automatisierungsskripte reibungslos funktionieren.
Selektorprobleme können die Skriptausführung oft unterbrechen. So beheben Sie sie effektiv:
async function findElement(page) {
try {
const element = await page.waitForSelector('[data-testid="target"]', {
timeout: 5000
});
return element;
} catch {
return page.waitForSelector('.target-class', {
timeout: 5000
});
}
}
Für Elemente innerhalb von iframes oder Schatten DOM, verwenden Sie diese Ansätze:
// Access iframe content
const frame = await page.frames().find(f => f.name() === 'content-frame');
const button = await frame.$('button[data-hook="create"]');
// Handle Shadow DOM elements
await page.evaluateHandle(selector => {
const element = document.querySelector('parent-element')
.shadowRoot
.querySelector(selector);
return element;
}, 'target-selector');
Durch die ordnungsgemäße Handhabung von Selektoren wird sichergestellt, dass Ihre Skripte Elemente zuverlässig finden.
Sobald die Selektoren stabil sind, ist die Verwaltung des Timings für eine reibungslose Ausführung von entscheidender Bedeutung:
await page.setDefaultNavigationTimeout(30000);
await page.setDefaultTimeout(10000);
async function waitForContent(page) {
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0' }),
page.click('#load-more-button')
]);
}
Hier ist eine Kurzreferenz für Zeitsteuerungen:
Timing-Problem | Die Lösung | Umsetzung |
---|---|---|
Laden der Seite | waitForNavigation | Warten Sie, bis das Netzwerk inaktiv ist |
Dynamischer Inhalt | warteAufAuswahl | Mit entsprechendem Timeout verwenden |
AJAX-Aktualisierungen | warteAufAntwort | Überwachen Sie bestimmte Netzwerkanforderungen |
Diese Strategien helfen dabei, das Timing Ihres Skripts an das Seitenverhalten anzupassen.
Auch mit soliden Selektor- und Timing-Strategien kann es zu Browserabstürzen kommen. So minimieren und beheben Sie diese:
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--enable-gpu',
'--no-first-run',
'--disable-extensions'
]
});
Zur Wiederherstellung nach einem Absturz:
let browser;
try {
browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('error', err => {
console.error('Page crashed:', err);
});
await page.goto('https://example.com');
} catch (error) {
console.error('Browser error:', error);
} finally {
if (browser) {
await browser.close();
}
}
Wenn Sie unter Linux arbeiten, prüfen Sie, ob Abhängigkeiten fehlen:
ldd chrome | grep not
Um die Ressourcennutzung zu optimieren, passen Sie die Browser-Flags an:
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
Richten Sie die automatische Wiederherstellung für zusätzliche Ausfallsicherheit ein:
async function checkAndRecoverPage(page) {
if (!page.isClosed()) {
try {
await page.reload();
} catch {
page = await browser.newPage();
}
}
return page;
}
Verbessern Sie Ihre Skripte für eine einfachere Wartung und schnellere Fehlerbehebung, indem Sie auf bewährten Debugging-Techniken aufbauen.
Sorgen Sie dafür, dass Ihr Code lesbar bleibt, indem Sie Konfigurationen gruppieren und klare, beschreibende Namen verwenden:
// Group related configurations
const browserConfig = {
headless: false,
defaultViewport: { width: 1920, height: 1080 },
args: ['--no-sandbox', '--disable-setuid-sandbox']
};
// Use descriptive function names
async function validatePageContent(page) {
const pageTitle = await page.title();
console.log(`Validating content for page: ${pageTitle}`);
const contentExists = await page.evaluate(() => {
const mainContent = document.querySelector('.main-content');
return {
hasHeader: !!document.querySelector('header'),
hasContent: !!mainContent,
contentLength: mainContent?.textContent.length || 0
};
});
return contentExists;
}
Teilen Sie Ihre Skripte in separate Module auf, um das Debuggen zu vereinfachen. Dieser Ansatz isoliert Selektoren, Aktionen und Validierungen und erleichtert so das Auffinden und Beheben von Fehlern.
// selectors.js
export const SELECTORS = {
loginForm: '#login-form',
submitButton: '[data-testid="submit-btn"]',
errorMessage: '.error-notification'
};
// actions.js
export async function performLogin(page, credentials) {
await page.type(SELECTORS.loginForm + ' input[name="username"]', credentials.username);
await page.type(SELECTORS.loginForm + ' input[name="password"]', credentials.password);
await Promise.all([
page.waitForNavigation(),
page.click(SELECTORS.submitButton)
]);
}
// validators.js
export async function checkLoginStatus(page) {
const errorElement = await page.$(SELECTORS.errorMessage);
if (errorElement) {
throw new Error('Login failed: ' + await page.evaluate(el => el.textContent, errorElement));
}
}
Diese modulare Struktur organisiert nicht nur Ihren Code, sondern trägt auch zur Optimierung der Fehlerverfolgung bei.
Richten Sie eine Fehlerverfolgung ein, um Probleme schnell zu identifizieren und einen detaillierten Kontext für die Fehlerbehebung bereitzustellen:
class PuppeteerError extends Error {
constructor(message, action, selector) {
super(message);
this.name = 'PuppeteerError';
this.action = action;
this.selector = selector;
this.timestamp = new Date().toISOString();
}
}
async function executeWithTracking(page, action, description) {
try {
await action();
} catch (error) {
const screenshot = await page.screenshot({
path: `error-${Date.now()}.png`,
fullPage: true
});
throw new PuppeteerError(
`Failed to ${description}`,
error.message,
error.selector
);
}
}
Sie können die Protokollierung von Konsolenfehlern und -warnungen auch automatisieren:
page.on('console', message => {
const type = message.type();
const text = message.text();
if (type === 'error' || type === 'warning') {
console.log(`[${type.toUpperCase()}] ${text}`);
// Log to external service or file
logger.log({
level: type,
message: text,
timestamp: new Date().toISOString(),
url: page.url()
});
}
});
Fügen Sie Validierungsprüfungen hinzu, um sicherzustellen, dass kritische Vorgänge erfolgreich abgeschlossen werden:
async function validateOperation(page, action) {
const beforeState = await page.evaluate(() => ({
url: window.location.href,
elements: document.querySelectorAll('*').length
}));
await action();
const afterState = await page.evaluate(() => ({
url: window.location.href,
elements: document.querySelectorAll('*').length
}));
return {
urlChanged: beforeState.url !== afterState.url,
elementsDelta: afterState.elements - beforeState.elements
};
}
Diese Techniken helfen Ihnen in Kombination mit früheren Debugging-Methoden dabei, Probleme schnell zu identifizieren und zu beheben und gleichzeitig die Wartbarkeit Ihrer Skripte aufrechtzuerhalten.
Verwenden des visuellen Debuggens im Headful-Modus mit slowMo
ermöglicht sofortiges Feedback zu Skripten und präzise Zeitanpassungen. Für detailliertere Szenarien bietet das DevTools-Protokoll schrittweises Debugging und Zugriff auf Prozessprotokolle für tiefere Einblicke.
const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true,
dumpio: true
});
Um Ihren Arbeitsablauf zu verbessern, sollten Sie neben diesen Debugging-Methoden auch kontinuierliche Überwachungs- und Ressourcenverwaltungspraktiken integrieren.
Nachdem Sie nun über solide Grundlagen in Debugging-Techniken verfügen, erfahren Sie hier, wie Sie Ihre Puppeteer-Skripte optimieren und warten können:
puppeteer-extra-plugin-stealth
Plugin zur Minimierung der Automatisierungserkennung und Reduzierung von Skriptfehlern.
Hier ist ein Beispiel für eine Bereinigungsfunktion zur effektiven Verwaltung von Ressourcen:
async function cleanupResources(page) {
await page.evaluate(() => {
if (window.performance.memory) {
console.log(`Heap size limit: ${(window.performance.memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2)} MB`);
}
});
await page.close();
}
Bleiben Sie auf dem Laufenden, indem Sie das Puppeteer GitHub-Repository regelmäßig auf Updates, neue Funktionen und Best Practices überprüfen. Wenn Sie Ihr Toolkit aktuell halten, bleiben Ihre Skripte auch bei sich ändernden Webtechnologien effizient und anpassungsfähig.