Débogage des scripts Puppeteer : du mode ralenti aux techniques avancées
Maîtrisez les techniques de débogage essentielles pour les scripts Puppeteer, des méthodes visuelles à la gestion avancée des erreurs, afin d'améliorer la fiabilité des scripts.

Débogage Marionnettiste Les scripts peuvent sembler complexes, mais maîtriser quelques techniques clés peut vous faire gagner du temps et vous éviter bien des frustrations. Voici un bref aperçu de ce que vous apprendrez :
- Commencez par le débogage visuel: Utilisation
slowMomode et mode navigateur headful pour regarder votre script en action. - Erreurs de capture: Ajouter
try-catchbloque et automatise les captures d'écran d'erreurs pour un meilleur dépannage. - Exploiter les journaux de la console:Suivez les erreurs de page, les demandes ayant échoué et les messages personnalisés pour des informations plus approfondies.
- Sélecteurs de poignées et synchronisation:Utilisez des stratégies de sélection robustes et gérez les délais d’attente pour éviter les pièges courants.
- Organisez votre code: Divisez les scripts en modules pour les actions, les sélecteurs et les validations afin de simplifier la maintenance.
Exemple de configuration rapide :
<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>
});
Conseils de débogage :
- Activer la journalisation: Courir avec
DEBUG="puppeteer:*"pour les journaux détaillés. - Utiliser des captures d'écran: Capturez les états de la page pour voir ce qui s'est mal passé.
- Gérer les ressources:Nettoyez toujours les instances du navigateur et de la page pour éviter les plantages.
En combinant ces techniques, vous rationaliserez votre processus de débogage et améliorerez la fiabilité de vos scripts Puppeteer.
Configuration de l'environnement de débogage
Paramètres de débogage de base
Configurez Puppeteer pour le débogage avec ces options de lancement :
<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>
});
Pour activer la journalisation détaillée, exécutez votre script avec la commande suivante :
DEBUG=<span class="hljs-string">"puppeteer:*"</span> node script.js
Une fois configuré, utilisez les outils de débogage pour analyser et affiner le comportement de votre script.
Outils de débogage requis
Voici quelques outils pour vous aider à résoudre les problèmes efficacement :
| Outil | Interet | Élément clé |
|---|---|---|
| Chrome DevTools | Inspecter les scripts | Console et outils réseau |
| Débogueur VS Code | Gérer les points d'arrêt | Exécution étape par étape |
| Utilitaire de capture d'écran | Dépannage visuel | Capturer les états des pages |
Vous pouvez également ajouter des points de contrôle dans votre code pour une meilleure visibilité :
<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> });
Organisation du script
Une bonne organisation est tout aussi importante que les outils utilisés. Décomposez votre script en modules logiques et intégrez la gestion des erreurs pour un débogage plus fluide :
<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> });
}
Pour réduire les risques de détection de robot, intégrez le plugin furtif :
<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>());
Enfin, assurez une bonne gestion des ressources en mettant en œuvre des procédures de nettoyage :
<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>();
}
Cette configuration fournit une base solide pour le débogage visuel et de la console dans vos projets.
Marionnettiste - 3 approches à considérer lors du débogage
Méthodes de débogage visuel
Observer vos scripts en action peut révéler des problèmes que l'analyse de code traditionnelle pourrait manquer. Ces méthodes élargissent vos options de débogage au-delà des journaux de console et du suivi des erreurs.
Guide du mode SlowMo
SlowMo introduit un délai entre les actions du Marionnettiste, ce qui facilite le suivi de ce qui se passe :
<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>
});
L'espace slowMo La valeur (en millisecondes) contrôle le délai entre les actions. Ajustez-la en fonction de vos tests :
| Type d'opération | SlowMo recommandé (ms) | Case Study |
|---|---|---|
| Des clics simples | 100-250 | Étapes de navigation de base |
| Remplissage de formulaire | 250-500 | Test de validation des entrées |
| Contenu dynamique | 500-1000 | Vérification des états de chargement |
Une fois que vous avez configuré SlowMo, associez-le au mode d'affichage du navigateur pour surveiller le comportement de l'interface utilisateur pendant l'exécution du script.
Mode d'affichage du navigateur
Le mode d'affichage du navigateur vous permet de voir votre script s'exécuter dans une fenêtre de navigateur visible, ce qui est particulièrement utile pour déboguer du contenu dynamique et des interactions complexes.
<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>]
});
, par exemple en : Acmé Corp.L'équipe d'assurance qualité a utilisé ce mode en juin 2024 pour dépanner un script de scraping web. Elle a identifié des sélecteurs incorrects et les a corrigés, réduisant ainsi le temps de débogage de 40 %.
Pour compléter cela, capturez des captures d’écran des états visuels importants pour une analyse plus approfondie.
Enregistrement visuel
Les captures d'écran et les vidéos peuvent créer un enregistrement clair de l'exécution de votre script, ce qui facilite le débogage :
<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>
});
Commencez par activer le mode d'affichage du navigateur, utilisez SlowMo pour un suivi détaillé et documentez les moments clés avec des captures d'écran. Ensemble, ces étapes créent un processus de débogage visuel complet.
Méthodes de débogage de la console
Les méthodes de console offrent un moyen simple d'obtenir des informations textuelles sur le comportement de vos scripts. Ces sorties, associées au débogage visuel, vous fournissent des détails précis sur l'exécution des scripts.
Suivi des messages de la console
Puppeteer facilite la capture des messages du navigateur avec des gestionnaires d'événements comme ceux-ci :
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>());
});
Cette configuration crée un système de journalisation qui suit les messages de la console, les erreurs de page et les requêtes ayant échoué. Pour plus de clarté, vous pouvez classer les messages par type :
| Type de message | Interet | Exemple de sortie |
|---|---|---|
| Historique | Informations générales. | Flux d'exécution standard |
| Erreur | Problèmes majeurs | Opérations échouées |
| Avertissement | Préoccupations potentielles | Ralentissements des performances |
| Infos | mises à jour d'état | Achèvement de la tâche |
Meilleures pratiques pour Console.log
L'utilisation de console.log Une gestion judicieuse peut grandement faciliter le débogage. Placez les journaux de manière stratégique pour suivre la progression et identifier les problèmes :
<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>);
Méthodes de journalisation étendues
Pour les problèmes plus complexes, les techniques de journalisation avancées peuvent changer la donne :
<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>);
Une équipe a constaté une baisse de 40 % des échecs de test après avoir adopté une journalisation détaillée du protocole.
<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>
Ces méthodes ajoutent une couche textuelle à votre processus de débogage, vous aidant à détecter et à résoudre les problèmes plus efficacement.
sbb-itb-23997f1
Méthodes de débogage avancées
Le débogage de scripts Puppeteer complexes implique l'utilisation de stratégies efficaces de gestion des erreurs et de techniques avancées pour garantir le bon fonctionnement des scripts.
Try-Catch pour la gestion des erreurs
Utilisez le blocs try-catch pour gérer efficacement les erreurs et maintenir votre script en cours d'exécution :
<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>
}
}
}
Vous pouvez améliorer la gestion des erreurs en combinant des blocs try-catch avec des classes d'erreurs personnalisées pour une meilleure catégorisation et une meilleure réponse.
Classes d'erreur personnalisées
La création de classes d'erreurs personnalisées vous aide à identifier et à classer les problèmes plus efficacement :
<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>;
}
}
Ces classes vous permettent de suivre et de déboguer les opérations asynchrones avec plus de clarté.
Débogage du code asynchrone
Le code asynchrone présente souvent des problèmes de timing et des promesses non tenues. Résolvez ces problèmes avec les techniques suivantes :
<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>
});
}
}
En utilisant le debugInfo interface, vous pouvez surveiller les rappels en attente et identifier les promesses non résolues lors de la communication du protocole du navigateur.
| Niveau de débogage | Interet | Mise en œuvre |
|---|---|---|
| Basic | Gérer les erreurs courantes | Blocs try-catch standard |
| Intermédiaire | Classer les erreurs | Hiérarchie de classes d'erreurs personnalisées |
| Avancé | Suivre les problèmes de protocole | Surveillance de l'interface de débogage |
Solutions aux problèmes courants
Cette section aborde les défis fréquents rencontrés avec Puppeteer et fournit des correctifs clairs pour assurer le bon fonctionnement de vos scripts d'automatisation.
Problèmes de sélection
Les problèmes de sélecteur peuvent souvent perturber l'exécution des scripts. Voici comment les gérer efficacement :
<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>
});
}
}
Pour les éléments à l'intérieur des iframes ou DOM de l'ombre, utilisez ces approches :
<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>);
Une gestion appropriée des sélecteurs garantit que vos scripts localisent les éléments de manière fiable.
Problèmes de timing
Une fois les sélecteurs stables, la gestion du timing est cruciale pour une exécution fluide :
<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>)
]);
}
Voici une référence rapide pour les commandes de synchronisation :
| Problème de timing | Solution | Mise en œuvre |
|---|---|---|
| Chargement de la page | attendre la navigation | Attendez que le réseau soit inactif |
| Contenu dynamique | attendre le sélecteur | Utiliser avec un délai d'expiration approprié |
| Mises à jour AJAX | attendre la réponse | Surveiller les demandes réseau spécifiques |
Ces stratégies aident à aligner le timing de votre script avec le comportement de la page.
Corrections de plantages du navigateur
Même avec des stratégies de sélection et de synchronisation efficaces, des plantages de navigateur peuvent survenir. Voici comment les minimiser et les corriger :
<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>
]
});
Pour la récupération après incident :
<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>();
}
}
Si vous travaillez sous Linux, vérifiez les dépendances manquantes :
ldd chrome | grep not
Pour optimiser l'utilisation des ressources, ajustez les indicateurs du navigateur :
<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>
]
});
Configurez la récupération automatique pour une résilience accrue :
<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;
}
Optimisation du débogage des scripts
Améliorez vos scripts pour une maintenance plus facile et une résolution d’erreurs plus rapide en vous appuyant sur des techniques de débogage éprouvées.
Clarté du code
Gardez votre code lisible en regroupant les configurations et en utilisant des noms clairs et descriptifs :
<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;
}
Organisation des modules
Divisez vos scripts en modules distincts pour simplifier le débogage. Cette approche isole les sélecteurs, les actions et les validations, facilitant ainsi la localisation et la correction des erreurs.
<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));
}
}
Cette structure modulaire organise non seulement votre code, mais contribue également à rationaliser le suivi des erreurs.
Configuration du suivi des erreurs
Configurez le suivi des erreurs pour identifier rapidement les problèmes et fournir un contexte détaillé pour le débogage :
<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>
);
}
}
Vous pouvez également automatiser la journalisation des erreurs et des avertissements de la console :
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>()
});
}
});
Validation des opérations critiques
Ajoutez des contrôles de validation pour garantir que les opérations critiques se terminent avec succès :
<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>
};
}
Ces techniques, combinées aux méthodes de débogage antérieures, vous aident à identifier et à résoudre rapidement les problèmes tout en gardant vos scripts maintenables.
Conclusion
Techniques de débogage clés
Utilisation du débogage visuel en mode headful avec slowMo Permet un retour immédiat sur les scripts et des ajustements de timing précis. Pour des scénarios plus détaillés, le protocole DevTools propose un débogage étape par étape et un accès aux journaux de processus pour une analyse plus approfondie.
<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>
});
Pour améliorer votre flux de travail, envisagez d’intégrer des pratiques de surveillance continue et de gestion des ressources parallèlement à ces méthodes de débogage.
Prochaines étapes
Maintenant que vous disposez d'une base solide en techniques de débogage, voici comment vous pouvez optimiser et maintenir vos scripts Puppeteer :
- Suivi de la performanceUtilisez une journalisation détaillée pour suivre les temps d'exécution et l'utilisation des ressources. Cela permet d'identifier les goulots d'étranglement et d'optimiser le débogage.
- Prévention des erreurs: Ajouter le
puppeteer-extra-plugin-stealthplugin pour minimiser la détection d'automatisation et réduire les échecs de script. - Gestion des ressources:Concentrez-vous sur une utilisation efficace de la mémoire et implémentez des routines de nettoyage pour assurer le bon fonctionnement de vos scripts.
Voici un exemple de fonction de nettoyage pour gérer efficacement les ressources :
<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>();
}
Gardez une longueur d'avance en consultant régulièrement le dépôt GitHub de Puppeteer pour connaître les mises à jour, les nouvelles fonctionnalités et les bonnes pratiques. Maintenir votre boîte à outils à jour garantit l'efficacité et l'adaptabilité de vos scripts à l'évolution des technologies web.
articles similaires
- Installation et configuration de Puppeteer : résolution des problèmes courants de dépendance et de Chromium
- Optimisation des stratégies d'attente dans Puppeteer : Guide complet des méthodes d'attente
- Automatisation du navigateur avec Puppeteer et JavaScript : mise en œuvre pratique dans Node.js
- Configuration du mode sans tête dans Puppeteer : équilibre entre vitesse et fonctionnalités



