Abonnements
PRODUIT
SOLUTIONS
par cas d'utilisation
AI Gestion du leadFacturationRéseaux SociauxGestion de projetGestion des donnéespar industrie
en savoir plus
BlogGabaritsVidéosYoutubeRESSOURCES
COMMUNAUTÉS ET RÉSEAUX SOCIAUX
PARTENAIRES
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 :
slowMo
mode et mode navigateur headful pour regarder votre script en action.try-catch
bloque et automatise les captures d'écran d'erreurs pour un meilleur dépannage.const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true
});
DEBUG="puppeteer:*"
pour les journaux détaillés.En combinant ces techniques, vous rationaliserez votre processus de débogage et améliorerez la fiabilité de vos scripts Puppeteer.
Configurez Puppeteer pour le débogage avec ces options de lancement :
const browser = await puppeteer.launch({
headless: false,
slowMo: 20,
devtools: true
});
Pour activer la journalisation détaillée, exécutez votre script avec la commande suivante :
DEBUG="puppeteer:*" node script.js
Une fois configuré, utilisez les outils de débogage pour analyser et affiner le comportement de votre script.
Voici quelques outils pour vous aider à résoudre les problèmes efficacement :
Outil | Objectif | Élément clé |
---|---|---|
Chrome DevTools | Inspecter les scripts | Console et outils réseau |
Code VS Debugger | 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é :
await page.screenshot({ path: 'before_click.png' });
await page.click('#button');
await page.screenshot({ path: 'after_click.png' });
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 :
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' });
}
Pour réduire les risques de détection de robot, intégrez le plugin furtif :
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
Enfin, assurez une bonne gestion des ressources en mettant en œuvre des procédures de nettoyage :
async function cleanup() {
if (page) await page.close();
if (browser) await browser.close();
}
Cette configuration fournit une base solide pour le débogage visuel et de la console dans vos projets.
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.
SlowMo introduit un délai entre les actions du Marionnettiste, ce qui facilite le suivi de ce qui se passe :
const browser = await puppeteer.launch({
headless: false,
slowMo: 250,
devtools: true
});
Le 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.
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.
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1700, height: 800 },
args: ['--start-maximized']
});
Par exemple, 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.
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 :
// 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
});
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.
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.
Puppeteer facilite la capture des messages du navigateur avec des gestionnaires d'événements comme ceux-ci :
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());
});
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 | Objectif | 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 |
Info | mises à jour d'état | Achèvement de la tâche |
En utilisant 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 :
// 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);
Pour les problèmes plus complexes, les techniques de journalisation avancées peuvent changer la donne :
// 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);
Une équipe a constaté une baisse de 40 % des échecs de test après avoir adopté une journalisation détaillée du protocole.
// Filter out specific network domain messages
// Command: DEBUG="puppeteer:*" DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'
Ces méthodes ajoutent une couche textuelle à votre processus de débogage, vous aidant à détecter et à résoudre les problèmes plus efficacement.
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.
Utilisez blocs try-catch pour gérer efficacement les erreurs et maintenir votre script en cours d'exécution :
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
}
}
}
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.
La création de classes d'erreurs personnalisées vous aide à identifier et à classer les problèmes plus efficacement :
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';
}
}
Ces classes vous permettent de suivre et de déboguer les opérations asynchrones avec plus de clarté.
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 :
// 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
});
}
}
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 | Objectif | Implantation |
---|---|---|
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 |
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.
Les problèmes de sélecteur peuvent souvent perturber l'exécution des scripts. Voici comment les gérer efficacement :
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
});
}
}
Pour les éléments à l'intérieur des iframes ou DOM de l'ombre, utilisez ces approches :
// 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');
Une gestion appropriée des sélecteurs garantit que vos scripts localisent les éléments de manière fiable.
Une fois les sélecteurs stables, la gestion du timing est cruciale pour une exécution fluide :
await page.setDefaultNavigationTimeout(30000);
await page.setDefaultTimeout(10000);
async function waitForContent(page) {
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0' }),
page.click('#load-more-button')
]);
}
Voici une référence rapide pour les commandes de synchronisation :
Problème de timing | Solution | Implantation |
---|---|---|
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.
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 :
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--enable-gpu',
'--no-first-run',
'--disable-extensions'
]
});
Pour la récupération après incident :
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();
}
}
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 :
const browser = await puppeteer.launch({
args: [
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
Configurez la récupération automatique pour une résilience accrue :
async function checkAndRecoverPage(page) {
if (!page.isClosed()) {
try {
await page.reload();
} catch {
page = await browser.newPage();
}
}
return page;
}
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.
Gardez votre code lisible en regroupant les configurations et en utilisant des noms clairs et descriptifs :
// 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;
}
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.
// 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));
}
}
Cette structure modulaire organise non seulement votre code, mais contribue également à rationaliser le suivi des erreurs.
Configurez le suivi des erreurs pour identifier rapidement les problèmes et fournir un contexte détaillé pour le débogage :
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
);
}
}
Vous pouvez également automatiser la journalisation des erreurs et des avertissements de la console :
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()
});
}
});
Ajoutez des contrôles de validation pour garantir que les opérations critiques se terminent avec succès :
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
};
}
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.
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.
const browser = await puppeteer.launch({
headless: false,
slowMo: 100,
devtools: true,
dumpio: true
});
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.
Maintenant que vous disposez d'une base solide en techniques de débogage, voici comment vous pouvez optimiser et maintenir vos scripts Puppeteer :
puppeteer-extra-plugin-stealth
plugin pour minimiser la détection d'automatisation et réduire les échecs de script.
Voici un exemple de fonction de nettoyage pour gérer efficacement les ressources :
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();
}
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.