Debuggen von Puppeteer-Skripten: Vom SlowMo-Modus bis zu fortgeschrittenen Techniken
Meistern Sie die wichtigsten Debugging-Techniken für Puppeteer-Skripte, von visuellen Methoden bis hin zur fortgeschrittenen Fehlerbehandlung, um die Zuverlässigkeit der Skripte zu verbessern.

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:
- Beginnen Sie mit visuellem Debugging: Benutzen
slowMoModus und Headful-Browsermodus, um Ihr Skript in Aktion zu sehen. - Fehler erfassen: Hinzufügen
try-catchBlöcke und automatisieren Sie Fehler-Screenshots für eine bessere Fehlerbehebung. - Nutzen Sie Konsolenprotokolle: Verfolgen Sie Seitenfehler, fehlgeschlagene Anfragen und benutzerdefinierte Nachrichten, um tiefere Einblicke zu erhalten.
- Griffauswahl und Timing: Verwenden Sie robuste Auswahlstrategien und verwalten Sie Timeouts, um häufige Fehler zu vermeiden.
- Organisieren Sie Ihren Code: Teilen Sie Skripte in Module für Aktionen, Selektoren und Validierungen auf, um die Wartung zu vereinfachen.
Beispiel für eine schnelle Einrichtung:
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">slowMo</span>: <span class="hljs-number">100</span>,
<span class="hljs-attr">devtools</span>: <span class="hljs-literal">true</span>
});
Tipps zur Fehlerbehebung:
- Aktiviere das Logging: Ausführen mit
DEBUG="puppeteer:*"für detaillierte Protokolle. - Verwenden Sie Screenshots: Erfassen Sie Seitenzustände, um zu sehen, was schiefgelaufen ist.
- Ressourcen verwalten: Bereinigen Sie immer Browser- und Seiteninstanzen, um Abstürze zu vermeiden.
Durch die Kombination dieser Techniken optimieren Sie Ihren Debugging-Prozess und verbessern die Zuverlässigkeit Ihrer Puppeteer-Skripte.
Einrichten der Debug-Umgebung
Grundlegende Debug-Einstellungen
Richten Sie Puppeteer mit diesen Startoptionen zum Debuggen ein:
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">slowMo</span>: <span class="hljs-number">20</span>,
<span class="hljs-attr">devtools</span>: <span class="hljs-literal">true</span>
});
Um eine detaillierte Protokollierung zu aktivieren, führen Sie Ihr Skript mit dem folgenden Befehl aus:
DEBUG=<span class="hljs-string">"puppeteer:*"</span> node script.js
Verwenden Sie nach der Konfiguration Debugging-Tools, um das Verhalten Ihres Skripts zu analysieren und zu verfeinern.
Erforderliche Debug-Tools
Hier sind einige Tools, die Ihnen dabei helfen, Probleme effektiv zu lösen:
| Werkzeug | Zweck | 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:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({ <span class="hljs-attr">path</span>: <span class="hljs-string">'before_click.png'</span> });
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">click</span>(<span class="hljs-string">'#button'</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({ <span class="hljs-attr">path</span>: <span class="hljs-string">'after_click.png'</span> });
Skriptorganisation
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:
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'#target-element'</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">click</span>(<span class="hljs-string">'#target-element'</span>);
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`Navigation failed: <span class="hljs-subst">${error.message}</span>`</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({ <span class="hljs-attr">path</span>: <span class="hljs-string">'error-state.png'</span> });
}
Um die Wahrscheinlichkeit einer Bot-Erkennung zu verringern, integrieren Sie das Stealth-Plugin:
<span class="hljs-keyword">const</span> puppeteer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'puppeteer-extra'</span>);
<span class="hljs-keyword">const</span> <span class="hljs-title class_">StealthPlugin</span> = <span class="hljs-built_in">require</span>(<span class="hljs-string">'puppeteer-extra-plugin-stealth'</span>);
puppeteer.<span class="hljs-title function_">use</span>(<span class="hljs-title class_">StealthPlugin</span>());
Stellen Sie abschließend eine ordnungsgemäße Ressourcenverwaltung sicher, indem Sie Bereinigungsverfahren implementieren:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">cleanup</span>(<span class="hljs-params"></span>) {
<span class="hljs-keyword">if</span> (page) <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">close</span>();
<span class="hljs-keyword">if</span> (browser) <span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">close</span>();
}
Dieses Setup bietet eine solide Grundlage für das visuelle und Konsolen-Debugging in Ihren Projekten.
Puppenspieler - 3 Ansätze, die beim Debuggen zu berücksichtigen sind
Visuelle Debugmethoden
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.
Anleitung zum SlowMo-Modus
SlowMo führt eine Verzögerung zwischen den Aktionen des Puppeteers ein, sodass Sie leichter verfolgen können, was passiert:
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">slowMo</span>: <span class="hljs-number">250</span>,
<span class="hljs-attr">devtools</span>: <span class="hljs-literal">true</span>
});
Die 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.
Browser-Ansichtsmodus
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.
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">defaultViewport</span>: { <span class="hljs-attr">width</span>: <span class="hljs-number">1700</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">800</span> },
<span class="hljs-attr">args</span>: [<span class="hljs-string">'--start-maximized'</span>]
});
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.
Visuelle Aufzeichnung
Screenshots und Videos können eine klare Aufzeichnung der Ausführung Ihres Skripts erstellen und so das Debuggen erleichtern:
<span class="hljs-comment">// Screenshot of a specific element</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({
<span class="hljs-attr">path</span>: <span class="hljs-string">'element-state.png'</span>,
<span class="hljs-attr">clip</span>: {
<span class="hljs-attr">x</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">y</span>: <span class="hljs-number">0</span>,
<span class="hljs-attr">width</span>: <span class="hljs-number">500</span>,
<span class="hljs-attr">height</span>: <span class="hljs-number">300</span>
}
});
<span class="hljs-comment">// Full-page screenshot</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({
<span class="hljs-attr">path</span>: <span class="hljs-string">'full-page.png'</span>,
<span class="hljs-attr">fullPage</span>: <span class="hljs-literal">true</span>
});
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.
Konsolen-Debugmethoden
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.
Konsolennachrichtenverfolgung
Puppeteer erleichtert das Erfassen von Browsernachrichten mit Ereignishandlern wie diesen:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'console'</span>, <span class="hljs-function"><span class="hljs-params">msg</span> =></span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'PAGE LOG:'</span>, msg.<span class="hljs-title function_">text</span>());
});
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'pageerror'</span>, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'PAGE ERROR:'</span>, err.<span class="hljs-property">message</span>);
});
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'requestfailed'</span>, <span class="hljs-function"><span class="hljs-params">request</span> =></span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'REQUEST FAILED:'</span>, request.<span class="hljs-title function_">url</span>());
});
Dieses Setup erstellt ein Protokollierungssystem, das Konsolenmeldungen, Seitenfehler und fehlgeschlagene Anfragen erfasst. Zur besseren Übersichtlichkeit können Sie die Meldungen nach Typ kategorisieren:
| Nachrichtentyp | Zweck | Beispielausgabe |
|---|---|---|
| Log | Allgemeine Hinweise | Standardausführungsablauf |
| Fehler | Große Probleme | Fehlgeschlagene Operationen |
| Warnung | Mögliche Bedenken | Leistungseinbußen |
| Infos | Status Updates | Aufgabe abgeschlossen |
Bewährte Methoden für Console.log
Die Verwendung von console.log Die sinnvolle Verwendung erleichtert das Debuggen erheblich. Platzieren Sie Protokolle strategisch, um den Fortschritt zu verfolgen und Probleme zu identifizieren:
<span class="hljs-comment">// Log before attempting to find an element</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Looking for element: <span class="hljs-subst">${selector}</span>`</span>);
<span class="hljs-keyword">const</span> element = <span class="hljs-keyword">await</span> page.$(selector);
<span class="hljs-comment">// Log after confirming the element exists</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Element found: <span class="hljs-subst">${!!element}</span>`</span>);
<span class="hljs-comment">// Log form data before filling it out</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Form data: <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(formData)}</span>`</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">type</span>(<span class="hljs-string">'#email'</span>, formData.<span class="hljs-property">email</span>);
Erweiterte Protokollierungsmethoden
Bei komplexeren Problemen können erweiterte Protokollierungstechniken entscheidende Vorteile bieten:
<span class="hljs-comment">// Enable detailed debugging for Puppeteer</span>
process.<span class="hljs-property">env</span>.<span class="hljs-property">DEBUG</span> = <span class="hljs-string">'puppeteer:*'</span>;
process.<span class="hljs-property">env</span>.<span class="hljs-property">DEBUG_MAX_STRING_LENGTH</span> = <span class="hljs-literal">null</span>;
<span class="hljs-comment">// Monitor pending protocol calls</span>
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">dumpio</span>: <span class="hljs-literal">true</span>
});
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(browser.<span class="hljs-property">debugInfo</span>.<span class="hljs-property">pendingProtocolErrors</span>);
Ein Team konnte nach der Einführung einer detaillierten Protokollierung einen Rückgang der Testfehler um 40 % verzeichnen.
<span class="hljs-comment">// Filter out specific network domain messages</span>
<span class="hljs-comment">// Command: DEBUG="puppeteer:*" DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'</span>
Diese Methoden fügen Ihrem Debugging-Prozess eine textbasierte Ebene hinzu und helfen Ihnen, Probleme effektiver zu erkennen und zu lösen.
sbb-itb-23997f1
Erweiterte Debug-Methoden
Das Debuggen komplexer Puppeteer-Skripte erfordert die Verwendung effektiver Fehlerbehandlungsstrategien und fortschrittlicher Techniken, um einen reibungslosen Ablauf der Skripte zu gewährleisten.
Try-Catch zur Fehlerbehandlung
Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, Try-Catch-Blöcke um Fehler effektiv zu verwalten und Ihr Skript am Laufen zu halten:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">navigateAndScreenshot</span>(<span class="hljs-params">url, selector</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">goto</span>(url, { <span class="hljs-attr">waitUntil</span>: <span class="hljs-string">'networkidle0'</span> });
<span class="hljs-keyword">const</span> element = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(selector, { <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span> });
<span class="hljs-keyword">await</span> element.<span class="hljs-title function_">screenshot</span>({ <span class="hljs-attr">path</span>: <span class="hljs-string">'element.png'</span> });
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">TimeoutError</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`Element <span class="hljs-subst">${selector}</span> not found within timeout`</span>);
<span class="hljs-comment">// Add recovery logic if needed</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">reload</span>();
} <span class="hljs-keyword">else</span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`Navigation failed: <span class="hljs-subst">${error.message}</span>`</span>);
<span class="hljs-keyword">throw</span> error; <span class="hljs-comment">// Re-throw unexpected errors</span>
}
}
}
Sie können die Fehlerbehandlung verbessern, indem Sie Try-Catch-Blöcke mit benutzerdefinierten Fehlerklassen kombinieren, um eine bessere Kategorisierung und Reaktion zu erzielen.
Benutzerdefinierte Fehlerklassen
Durch das Erstellen benutzerdefinierter Fehlerklassen können Sie Probleme effizienter lokalisieren und klassifizieren:
<span class="hljs-keyword">class</span> <span class="hljs-title class_">PuppeteerScriptError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Error</span> {
<span class="hljs-title function_">constructor</span>(<span class="hljs-params">message, details = {}</span>) {
<span class="hljs-variable language_">super</span>(message);
<span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'PuppeteerScriptError'</span>;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">details</span> = details;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">timestamp</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>().<span class="hljs-title function_">toISOString</span>();
}
}
<span class="hljs-keyword">class</span> <span class="hljs-title class_">SelectorError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">PuppeteerScriptError</span> {
<span class="hljs-title function_">constructor</span>(<span class="hljs-params">selector, context</span>) {
<span class="hljs-variable language_">super</span>(<span class="hljs-string">`Failed to find selector: <span class="hljs-subst">${selector}</span>`</span>, {
selector,
context,
<span class="hljs-attr">type</span>: <span class="hljs-string">'SELECTOR_ERROR'</span>
});
<span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'SelectorError'</span>;
}
}
Mit diesen Klassen können Sie asynchrone Vorgänge klarer verfolgen und debuggen.
Debuggen von asynchronem Code
Asynchroner Code führt häufig zu Zeitproblemen und uneingelösten Versprechen. Bewältigen Sie diese Probleme mit den folgenden Techniken:
<span class="hljs-comment">// Enable detailed debugging for protocol calls</span>
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">dumpio</span>: <span class="hljs-literal">true</span>
});
<span class="hljs-comment">// Monitor unresolved promises periodically</span>
<span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =></span> {
<span class="hljs-keyword">const</span> pending = browser.<span class="hljs-property">debugInfo</span>.<span class="hljs-property">pendingProtocolErrors</span>;
<span class="hljs-keyword">if</span> (pending.<span class="hljs-property">length</span> > <span class="hljs-number">0</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Pending protocol calls:'</span>, pending);
}
}, <span class="hljs-number">5000</span>);
<span class="hljs-comment">// Handle async errors with a timeout mechanism</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">safeExecute</span>(<span class="hljs-params">promiseFn</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">race</span>([
<span class="hljs-title function_">promiseFn</span>(),
<span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">_, reject</span>) =></span>
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> <span class="hljs-title function_">reject</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'Operation timed out'</span>)), <span class="hljs-number">30000</span>)
)
]);
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">`Operation failed: <span class="hljs-subst">${error.message}</span>`</span>);
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PuppeteerScriptError</span>(<span class="hljs-string">'Execution timeout'</span>, {
<span class="hljs-attr">originalError</span>: error,
<span class="hljs-attr">operation</span>: promiseFn.<span class="hljs-property">name</span>
});
}
}
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 | Zweck | Umsetzung |
|---|---|---|
| Grundlagen | Behandeln häufiger Fehler | Standardmäßige Try-Catch-Blöcke |
| Fortgeschrittener | Fehler klassifizieren | Benutzerdefinierte Fehlerklassenhierarchie |
| Erweitert | Protokollprobleme verfolgen | Debug-Schnittstellenüberwachung |
Lösungen für häufige Probleme
In diesem Abschnitt werden häufige Probleme mit Puppeteer behandelt und klare Lösungen bereitgestellt, damit Ihre Automatisierungsskripte reibungslos funktionieren.
Selektorprobleme
Selektorprobleme können die Skriptausführung oft unterbrechen. So beheben Sie sie effektiv:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">findElement</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> element = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'[data-testid="target"]'</span>, {
<span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span>
});
<span class="hljs-keyword">return</span> element;
} <span class="hljs-keyword">catch</span> {
<span class="hljs-keyword">return</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.target-class'</span>, {
<span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span>
});
}
}
Für Elemente innerhalb von iframes oder Schatten DOM, verwenden Sie diese Ansätze:
<span class="hljs-comment">// Access iframe content</span>
<span class="hljs-keyword">const</span> frame = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">frames</span>().<span class="hljs-title function_">find</span>(<span class="hljs-function"><span class="hljs-params">f</span> =></span> f.<span class="hljs-title function_">name</span>() === <span class="hljs-string">'content-frame'</span>);
<span class="hljs-keyword">const</span> button = <span class="hljs-keyword">await</span> frame.$(<span class="hljs-string">'button[data-hook="create"]'</span>);
<span class="hljs-comment">// Handle Shadow DOM elements</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluateHandle</span>(<span class="hljs-function"><span class="hljs-params">selector</span> =></span> {
<span class="hljs-keyword">const</span> element = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'parent-element'</span>)
.<span class="hljs-property">shadowRoot</span>
.<span class="hljs-title function_">querySelector</span>(selector);
<span class="hljs-keyword">return</span> element;
}, <span class="hljs-string">'target-selector'</span>);
Durch die ordnungsgemäße Handhabung von Selektoren wird sichergestellt, dass Ihre Skripte Elemente zuverlässig finden.
Timing-Probleme
Sobald die Selektoren stabil sind, ist die Verwaltung des Timings für eine reibungslose Ausführung von entscheidender Bedeutung:
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setDefaultNavigationTimeout</span>(<span class="hljs-number">30000</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setDefaultTimeout</span>(<span class="hljs-number">10000</span>);
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">waitForContent</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">all</span>([
page.<span class="hljs-title function_">waitForNavigation</span>({ <span class="hljs-attr">waitUntil</span>: <span class="hljs-string">'networkidle0'</span> }),
page.<span class="hljs-title function_">click</span>(<span class="hljs-string">'#load-more-button'</span>)
]);
}
Hier ist eine Kurzreferenz für Zeitsteuerungen:
| Timing-Problem | 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.
Fehlerbehebungen für Browserabstürze
Auch mit soliden Selektor- und Timing-Strategien kann es zu Browserabstürzen kommen. So minimieren und beheben Sie diese:
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">args</span>: [
<span class="hljs-string">'--disable-dev-shm-usage'</span>,
<span class="hljs-string">'--enable-gpu'</span>,
<span class="hljs-string">'--no-first-run'</span>,
<span class="hljs-string">'--disable-extensions'</span>
]
});
Zur Wiederherstellung nach einem Absturz:
<span class="hljs-keyword">let</span> browser;
<span class="hljs-keyword">try</span> {
browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>();
<span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">newPage</span>();
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'Page crashed:'</span>, err);
});
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">goto</span>(<span class="hljs-string">'https://example.com'</span>);
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'Browser error:'</span>, error);
} <span class="hljs-keyword">finally</span> {
<span class="hljs-keyword">if</span> (browser) {
<span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">close</span>();
}
}
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:
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">args</span>: [
<span class="hljs-string">'--disable-dev-shm-usage'</span>,
<span class="hljs-string">'--disable-accelerated-2d-canvas'</span>,
<span class="hljs-string">'--disable-gpu'</span>
]
});
Richten Sie die automatische Wiederherstellung für zusätzliche Ausfallsicherheit ein:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">checkAndRecoverPage</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">if</span> (!page.<span class="hljs-title function_">isClosed</span>()) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">reload</span>();
} <span class="hljs-keyword">catch</span> {
page = <span class="hljs-keyword">await</span> browser.<span class="hljs-title function_">newPage</span>();
}
}
<span class="hljs-keyword">return</span> page;
}
Skript-Debug-Optimierung
Verbessern Sie Ihre Skripte für eine einfachere Wartung und schnellere Fehlerbehebung, indem Sie auf bewährten Debugging-Techniken aufbauen.
Code-Klarheit
Sorgen Sie dafür, dass Ihr Code lesbar bleibt, indem Sie Konfigurationen gruppieren und klare, beschreibende Namen verwenden:
<span class="hljs-comment">// Group related configurations</span>
<span class="hljs-keyword">const</span> browserConfig = {
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">defaultViewport</span>: { <span class="hljs-attr">width</span>: <span class="hljs-number">1920</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">1080</span> },
<span class="hljs-attr">args</span>: [<span class="hljs-string">'--no-sandbox'</span>, <span class="hljs-string">'--disable-setuid-sandbox'</span>]
};
<span class="hljs-comment">// Use descriptive function names</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">validatePageContent</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">const</span> pageTitle = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">title</span>();
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Validating content for page: <span class="hljs-subst">${pageTitle}</span>`</span>);
<span class="hljs-keyword">const</span> contentExists = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">() =></span> {
<span class="hljs-keyword">const</span> mainContent = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.main-content'</span>);
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">hasHeader</span>: !!<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'header'</span>),
<span class="hljs-attr">hasContent</span>: !!mainContent,
<span class="hljs-attr">contentLength</span>: mainContent?.<span class="hljs-property">textContent</span>.<span class="hljs-property">length</span> || <span class="hljs-number">0</span>
};
});
<span class="hljs-keyword">return</span> contentExists;
}
Modulorganisation
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.
<span class="hljs-comment">// selectors.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">SELECTORS</span> = {
<span class="hljs-attr">loginForm</span>: <span class="hljs-string">'#login-form'</span>,
<span class="hljs-attr">submitButton</span>: <span class="hljs-string">'[data-testid="submit-btn"]'</span>,
<span class="hljs-attr">errorMessage</span>: <span class="hljs-string">'.error-notification'</span>
};
<span class="hljs-comment">// actions.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">performLogin</span>(<span class="hljs-params">page, credentials</span>) {
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">type</span>(<span class="hljs-variable constant_">SELECTORS</span>.<span class="hljs-property">loginForm</span> + <span class="hljs-string">' input[name="username"]'</span>, credentials.<span class="hljs-property">username</span>);
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">type</span>(<span class="hljs-variable constant_">SELECTORS</span>.<span class="hljs-property">loginForm</span> + <span class="hljs-string">' input[name="password"]'</span>, credentials.<span class="hljs-property">password</span>);
<span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">all</span>([
page.<span class="hljs-title function_">waitForNavigation</span>(),
page.<span class="hljs-title function_">click</span>(<span class="hljs-variable constant_">SELECTORS</span>.<span class="hljs-property">submitButton</span>)
]);
}
<span class="hljs-comment">// validators.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">checkLoginStatus</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">const</span> errorElement = <span class="hljs-keyword">await</span> page.$(<span class="hljs-variable constant_">SELECTORS</span>.<span class="hljs-property">errorMessage</span>);
<span class="hljs-keyword">if</span> (errorElement) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'Login failed: '</span> + <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function"><span class="hljs-params">el</span> =></span> el.<span class="hljs-property">textContent</span>, errorElement));
}
}
Diese modulare Struktur organisiert nicht nur Ihren Code, sondern trägt auch zur Optimierung der Fehlerverfolgung bei.
Fehlerverfolgungs-Setup
Richten Sie eine Fehlerverfolgung ein, um Probleme schnell zu identifizieren und einen detaillierten Kontext für die Fehlerbehebung bereitzustellen:
<span class="hljs-keyword">class</span> <span class="hljs-title class_">PuppeteerError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Error</span> {
<span class="hljs-title function_">constructor</span>(<span class="hljs-params">message, action, selector</span>) {
<span class="hljs-variable language_">super</span>(message);
<span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'PuppeteerError'</span>;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">action</span> = action;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">selector</span> = selector;
<span class="hljs-variable language_">this</span>.<span class="hljs-property">timestamp</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>().<span class="hljs-title function_">toISOString</span>();
}
}
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">executeWithTracking</span>(<span class="hljs-params">page, action, description</span>) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">await</span> <span class="hljs-title function_">action</span>();
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-keyword">const</span> screenshot = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">screenshot</span>({
<span class="hljs-attr">path</span>: <span class="hljs-string">`error-<span class="hljs-subst">${<span class="hljs-built_in">Date</span>.now()}</span>.png`</span>,
<span class="hljs-attr">fullPage</span>: <span class="hljs-literal">true</span>
});
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PuppeteerError</span>(
<span class="hljs-string">`Failed to <span class="hljs-subst">${description}</span>`</span>,
error.<span class="hljs-property">message</span>,
error.<span class="hljs-property">selector</span>
);
}
}
Sie können die Protokollierung von Konsolenfehlern und -warnungen auch automatisieren:
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'console'</span>, <span class="hljs-function"><span class="hljs-params">message</span> =></span> {
<span class="hljs-keyword">const</span> type = message.<span class="hljs-title function_">type</span>();
<span class="hljs-keyword">const</span> text = message.<span class="hljs-title function_">text</span>();
<span class="hljs-keyword">if</span> (type === <span class="hljs-string">'error'</span> || type === <span class="hljs-string">'warning'</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`[<span class="hljs-subst">${type.toUpperCase()}</span>] <span class="hljs-subst">${text}</span>`</span>);
<span class="hljs-comment">// Log to external service or file</span>
logger.<span class="hljs-title function_">log</span>({
<span class="hljs-attr">level</span>: type,
<span class="hljs-attr">message</span>: text,
<span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>().<span class="hljs-title function_">toISOString</span>(),
<span class="hljs-attr">url</span>: page.<span class="hljs-title function_">url</span>()
});
}
});
Validierung für kritische Vorgänge
Fügen Sie Validierungsprüfungen hinzu, um sicherzustellen, dass kritische Vorgänge erfolgreich abgeschlossen werden:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">validateOperation</span>(<span class="hljs-params">page, action</span>) {
<span class="hljs-keyword">const</span> beforeState = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">() =></span> ({
<span class="hljs-attr">url</span>: <span class="hljs-variable language_">window</span>.<span class="hljs-property">location</span>.<span class="hljs-property">href</span>,
<span class="hljs-attr">elements</span>: <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'*'</span>).<span class="hljs-property">length</span>
}));
<span class="hljs-keyword">await</span> <span class="hljs-title function_">action</span>();
<span class="hljs-keyword">const</span> afterState = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">() =></span> ({
<span class="hljs-attr">url</span>: <span class="hljs-variable language_">window</span>.<span class="hljs-property">location</span>.<span class="hljs-property">href</span>,
<span class="hljs-attr">elements</span>: <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'*'</span>).<span class="hljs-property">length</span>
}));
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">urlChanged</span>: beforeState.<span class="hljs-property">url</span> !== afterState.<span class="hljs-property">url</span>,
<span class="hljs-attr">elementsDelta</span>: afterState.<span class="hljs-property">elements</span> - beforeState.<span class="hljs-property">elements</span>
};
}
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.
Fazit
Wichtige Debugging-Techniken
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.
<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.<span class="hljs-title function_">launch</span>({
<span class="hljs-attr">headless</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">slowMo</span>: <span class="hljs-number">100</span>,
<span class="hljs-attr">devtools</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">dumpio</span>: <span class="hljs-literal">true</span>
});
Um Ihren Arbeitsablauf zu verbessern, sollten Sie neben diesen Debugging-Methoden auch kontinuierliche Überwachungs- und Ressourcenverwaltungspraktiken integrieren.
Nächste Schritte
Nachdem Sie nun über solide Grundlagen in Debugging-Techniken verfügen, erfahren Sie hier, wie Sie Ihre Puppeteer-Skripte optimieren und warten können:
- Leistungsüberwachung: Verwenden Sie detaillierte Protokollierung, um Ausführungszeiten und Ressourcennutzung zu verfolgen. Dies hilft, Engpässe zu identifizieren und das Debuggen effizienter zu gestalten.
- Fehlervermeidung: Ergänzen Sie die
puppeteer-extra-plugin-stealthPlugin zur Minimierung der Automatisierungserkennung und Reduzierung von Skriptfehlern. - Ressourcenmanagement: Konzentrieren Sie sich auf eine effiziente Speichernutzung und implementieren Sie Bereinigungsroutinen, damit Ihre Skripte reibungslos laufen.
Hier ist ein Beispiel für eine Bereinigungsfunktion zur effektiven Verwaltung von Ressourcen:
<span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">cleanupResources</span>(<span class="hljs-params">page</span>) {
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">() =></span> {
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">window</span>.<span class="hljs-property">performance</span>.<span class="hljs-property">memory</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Heap size limit: <span class="hljs-subst">${(<span class="hljs-variable language_">window</span>.performance.memory.jsHeapSizeLimit / <span class="hljs-number">1024</span> / <span class="hljs-number">1024</span>).toFixed(<span class="hljs-number">2</span>)}</span> MB`</span>);
}
});
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">close</span>();
}
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.
Ähnliche Artikel
- Installieren und Konfigurieren von Puppeteer: Lösen häufiger Abhängigkeits- und Chromium-Probleme
- Optimieren von Wartestrategien in Puppeteer: Ein vollständiger Leitfaden zu Wartemethoden
- Browserautomatisierung mit Puppeteer und JavaScript: Praktische Umsetzung in Node.js
- Headless-Modus in Puppeteer konfigurieren: Geschwindigkeit und Funktionalität ausbalancieren



