Vous voulez que vos scripts Puppeteer gèrent mieux les sites web dynamiques ? Voici l’essentiel : waitForFunction vous permet de définir des règles d’attente personnalisées pour garantir le bon fonctionnement de votre automatisation avec des contenus qui évoluent.
Pourquoi utiliser waitForFunction ?
- Contrôler le timing : attendez que des conditions précises soient remplies (par exemple, le chargement d’éléments ou la modification de texte).
- Gérer le contenu dynamique : idéal pour les sites web modernes et dynamiques.
- Éviter les erreurs : évitez les délais inutiles et les interactions prématurées.
Comment cela fonctionne :
- Écrivez des conditions JavaScript qui renvoient
truelorsqu’elles sont satisfaites. - Utilisez des options telles que la fréquence d’interrogation (
raf,mutationou millisecondes) et les délais d’expiration pour améliorer les performances. - Combinez des vérifications du DOM avec des réponses d’API pour des cas d’usage avancés.
Exemple :
await page.waitForFunction(
() => document.querySelector('.status').textContent === 'Ready'
);
Fonctionnalités clés :
- Surveillez la visibilité des éléments, leur contenu textuel ou leurs propriétés personnalisées.
- Combinez plusieurs conditions pour des workflows complexes.
- Gérez les délais d’expiration et les erreurs avec élégance.
Conseil : utilisez waitForFunction pour remplacer les appels sleep obsolètes et améliorer l’efficacité.
Aperçu rapide :
| Fonctionnalité | Rôle |
|---|---|
| Modes d’interrogation | Vérifie les conditions via « raf », « mutation » ou des intervalles personnalisés |
| Conditions personnalisées | Attend des états DOM spécifiques ou des réponses d’API |
| Gestion des délais d’expiration | Définit des délais propres à l’opération ou globaux |
Cette méthode garantit que vos scripts sont fiables, efficaces et prêts à relever tous les défis liés au contenu dynamique.
Comment attendre / suspendre l’exécution pendant N secondes dans puppeteer ?
Principes de base de waitForFunction
La méthode waitForFunction de Puppeteer vous permet de définir des conditions personnalisées que vos scripts doivent attendre avant de poursuivre leur exécution. Voici comment l’utiliser efficacement.
Comment écrire des fonctions d’attente simples
Voici une méthode simple pour créer une fonction d’attente :
// Wait until the input element has a specific value
await page.waitForFunction(
'document.getElementById("loginUsername").value === "hello"'
);
// Using an arrow function for a condition
await page.waitForFunction(
() => document.querySelector('.status').textContent === 'Ready'
);
L’élément essentiel est que votre fonction doit renvoyer une valeur véridique avant que le script puisse continuer [1].
Voyons maintenant comment la configurer pour optimiser ses performances.
Configuration des paramètres de fonction
Vous pouvez affiner waitForFunction en lui transmettant un objet d’options. Les paramètres clés incluent :
| Paramètre | Description | Valeurs courantes |
|---|---|---|
| polling | Fréquence de vérification de la condition | « raf », « mutation » ou millisecondes |
| timeout | Durée maximale d’attente | Par défaut : 30 000 ms (30 secondes) |
Modes d’interrogation [4] :
RequestAnimationFrame (« raf »)
Idéal pour surveiller les changements de style, car il vérifie les conditions à chaque image d’animation.Mutation Observer (« mutation »)
Utile pour suivre les modifications de la structure du DOM. Il déclenche des vérifications à chaque mise à jour du DOM.Intervalle personnalisé (millisecondes)
Par exemple, cette configuration vérifie la condition chaque seconde :await page.waitForFunction( () => document.readyState === 'complete', { polling: 1000, timeout: 5000 } );
Choisissez le mode d’interrogation selon vos besoins :
- Utilisez
'raf'pour les animations ou les mises à jour de style. - Préférez
'mutation'pour les modifications liées au DOM. - Définissez un intervalle personnalisé (en millisecondes) pour des cas d’usage plus larges.
Création de règles d’attente personnalisées
Vérification du statut d’affichage d’un élément
Pour confirmer qu’un élément est visible, vous pouvez vérifier sa présence et ses dimensions :
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Cela garantit que l’élément existe et possède des dimensions visibles dans la page. C’est particulièrement utile pour le contenu dynamique qui nécessite du temps pour se charger correctement [2].
Vérification du texte et des propriétés des éléments
Au-delà des vérifications visuelles, vous pouvez surveiller le contenu textuel ou des propriétés spécifiques des éléments :
// Wait for specific text content
await page.waitForFunction(
selector => {
const element = document.querySelector(selector);
return element && element.textContent.includes('Ready');
},
{},
'.status-message'
);
Pour des vérifications de propriétés plus détaillées, transmettez des arguments supplémentaires :
const expectedValue = 'completed';
const selector = '.status';
await page.waitForFunction(
(sel, val) => {
const element = document.querySelector(sel);
return element && element.getAttribute('data-state') === val;
},
{},
selector,
expectedValue
);
Combinaison de plusieurs règles d’attente
Après avoir testé des conditions individuelles, vous pouvez les combiner pour des situations plus complexes. Par exemple :
await page.waitForFunction(() => {
// Check multiple elements and conditions
const button = document.querySelector('.donate-button');
const searchBox = document.querySelector('.search-button');
return button &&
searchBox &&
button.offsetHeight > 0 &&
searchBox.offsetHeight > 0 &&
!button.disabled;
});
Pour gérer plusieurs éléments dotés de conditions indépendantes, utilisez des combinaisons de Promise [5] :
| Modèle d’attente | Cas d’usage | Implémentation |
|---|---|---|
| Tous les éléments | Attendre plusieurs éléments requis | Promise.all() |
| N’importe quel élément | Continuer lorsque le premier élément apparaît | Promise.race() |
| Logique personnalisée | Gérer des vérifications conditionnelles complexes | Fonctions d’attente combinées |
Pour les opérations asynchrones, vous pouvez créer des conditions d’attente avancées :
await page.waitForFunction(
async () => {
const response = await fetch('/api/status');
const data = await response.json();
return data.isReady && document.querySelector('.content').offsetHeight > 0;
},
{ polling: 'mutation' }
);
Cette méthode combine la validation des réponses d’API avec des vérifications des éléments du DOM, afin de garantir que les données comme le contenu visuel sont prêts [1].
sbb-itb-23997f1
Méthodes waitForFunction avancées
Écriture de conditions JavaScript complexes
Pour les applications web plus dynamiques, vous pouvez utiliser waitForFunction afin de créer des conditions JavaScript détaillées. Voici un exemple :
await page.waitForFunction(
(threshold) => {
const chart = document.querySelector('.tv-lightweight-charts');
const dataPoints = chart?.querySelectorAll('.data-point');
return chart &&
dataPoints?.length > threshold &&
Array.from(dataPoints).every(point =>
point.getBoundingClientRect().height > 0 &&
!point.classList.contains('loading')
);
},
{ polling: 'mutation' },
5
);
Ce script garantit que :
- Le conteneur du graphique existe.
- Un nombre minimal de points de données est présent.
- Tous les points de données sont visibles.
- Aucun point n’est en cours de chargement.
Vous pouvez également combiner des vérifications asynchrones avec des évaluations du DOM pour des situations plus complexes :
await page.waitForFunction(
async () => {
// Check if the container is ready
const container = document.querySelector('.dynamic-content');
if (!container || container.offsetHeight === 0) return false;
// Validate API response
try {
const response = await fetch('/api/status');
const data = await response.json();
return data.isReady && container.children.length > 0;
} catch {
return false;
}
},
{
polling: 'raf',
timeout: 30000
}
);
Cette approche combine les vérifications du DOM avec un appel d’API afin de garantir que l’interface utilisateur et le backend sont synchronisés.
Gestion des délais d’expiration et des erreurs
La gestion des délais d’expiration est essentielle lorsque vous utilisez waitForFunction. Voici un exemple de gestion efficace des délais :
try {
await page.setDefaultTimeout(60000); // Set a global timeout of 60 seconds
await page.waitForFunction(
() => {
const element = document.querySelector('.dynamic-element');
return element?.complete === true;
},
{
timeout: 45000, // Specific timeout for this operation
polling: 'mutation'
}
);
} catch (error) {
if (error.name === 'TimeoutError') {
console.error('Element state check timed out:', error.message);
await page.reload(); // Reload page as a fallback
}
throw error;
}
Voici un aperçu rapide des stratégies de délai d’expiration :
| Stratégie de délai d’expiration | Cas d’usage | Configuration |
|---|---|---|
| Délai par défaut | Opérations générales | page.setDefaultTimeout() |
| Délai de navigation | Chargements de page | page.setDefaultNavigationTimeout() |
| Spécifique à l’opération | Vérifications détaillées | Utilisez l’option timeout dans la méthode |
| Attente infinie | Délais connus | timeout: 0 |
Pour améliorer la gestion des erreurs :
- Ajustez les paramètres de délai selon la complexité de chaque opération.
- Utilisez des blocs
try-catchpour récupérer proprement après des erreurs. - Surveillez l’activité réseau pour identifier les goulots d’étranglement.
- Mettez en place des actions de secours, comme le rechargement de la page, lorsque des délais d’expiration surviennent.
- Vérifiez deux fois les sélecteurs pour éviter les délais inutiles.
Ces pratiques contribueront à rendre vos scripts à la fois fiables et efficaces.
Accélérer l’exécution de waitForFunction
Conseils de rapidité et de gestion des ressources
Pour exécuter waitForFunction plus efficacement, privilégiez des stratégies d’attente intelligentes et une bonne gestion des ressources. Utilisez les outils de développement du navigateur pour mesurer les temps de chargement et définir des délais précis.
// Optimize waiting with a networkidle strategy
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 30000
});
// Combine checks in a single evaluate call
await page.evaluate(() => {
const element = document.querySelector('.dynamic-content');
const isVisible = element?.offsetHeight > 0;
const hasData = element?.children.length > 0;
return isVisible && hasData;
});
Pour réduire l’utilisation des ressources :
- Bloquez les ressources inutiles telles que les images ou les polices.
- Utilisez
waitForSelectorouwaitForFunctionau lieu dewaitForTimeout, désormais obsolète. - Combinez plusieurs vérifications dans un seul appel
evaluateafin de réduire les communications entre le navigateur et Node.js.
| Stratégie | Impact sur les performances | Meilleur cas d’usage |
|---|---|---|
| networkidle2 | Modéré | Navigation sur une page |
| waitForSelector | Rapide | Vérifications d’un seul élément |
| waitForFunction | Variable | Conditions complexes |
| evaluate combiné | Le plus rapide | Vérifications de plusieurs éléments |
Ces méthodes permettent de résoudre des goulots d’étranglement courants, abordés dans la section suivante.
Résolution des problèmes courants
Les problèmes de performances proviennent souvent de modèles d’attente inefficaces. Voici comment les gérer :
Problèmes de sélecteurs
Des sélecteurs trop rigides peuvent provoquer des échecs. Simplifiez-les pour améliorer la fiabilité :
// Avoid rigid selectors like this
await page.waitForSelector('div.container > div:nth-child(2) > span.text-red');
// Use a more flexible approach
await page.waitForFunction(
() => document.querySelector('.text-red')?.offsetParent !== null
);
Gestion des ressources
Gérez les ressources et évitez les délais inutiles :
try {
await page.waitForFunction(
() => document.readyState === 'complete' &&
performance.now() > 1000
);
} catch (error) {
console.error('Page load timeout:', error.message);
}
« Puppeteer dispose d’une architecture pilotée par les événements, ce qui élimine une grande partie de l’instabilité potentielle. Les appels
sleep[undefined]inutiles n’ont pas leur place dans les scripts Puppeteer. » — readme de Puppeteer [6]
Encadrez toujours les méthodes d’attente dans des blocs try...catch afin de gérer les erreurs proprement et de proposer des solutions de secours. Cette approche garantit la robustesse et la fiabilité de vos scripts.
Cas d’usage courants des règles d’attente personnalisées
Chargement des produits d’une boutique en ligne
S’assurer que les produits se chargent correctement est indispensable pour collecter des données précises. Utilisez une règle d’attente personnalisée afin de suspendre l’exécution jusqu’au chargement complet des éléments de produit :
await page.waitForFunction(() => {
const products = document.querySelectorAll('.product-card');
return products.length > 0 && all images and prices fully load;
});
Pour davantage de précision, vous pouvez utiliser cette approche :
await page.waitForFunction(() => {
const productDetails = document.querySelector('.product-details');
return productDetails &&
productDetails.offsetHeight > 0 &&
productDetails.querySelector('.inventory-status') !== null;
}, {timeout: 30000});
Cela garantit que votre script attend le chargement de tous les éléments nécessaires, améliorant ainsi la fiabilité de la collecte de données dans les cas d’usage e-commerce.
Chargement de contenu dans les applications web modernes
Les applications web dynamiques nécessitent souvent des conditions d’attente spécifiques pour gérer le chargement du contenu. Par exemple, vous pouvez attendre qu’un élément particulier devienne entièrement visible :
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Si plusieurs sections doivent être chargées, combinez les conditions comme suit :
await page.waitForFunction(() => {
const contentLoaded = document.querySelector('.content').children.length > 0;
const dataUpdated = document.body.textContent.includes('Last updated:');
return contentLoaded && dataUpdated;
}, {polling: 1000});
Cette méthode permet de garantir que vos scripts d’automatisation interagissent de manière fluide avec le contenu dynamique.
Détection des messages d’erreur de formulaire
La détection des erreurs de formulaire repose sur une logique similaire aux vérifications de visibilité des éléments. Voici comment surveiller les messages d’erreur :
await page.waitForFunction(() => {
const errorContainer = document.querySelector('.error-messages');
const hasErrors = errorContainer?.children.length > 0;
const isVisible = errorContainer?.offsetParent !== null;
return hasErrors && isVisible;
});
Vous pouvez également suivre différents états de validation des formulaires à l’aide de conditions d’attente spécifiques :
| Type de validation | Condition d’attente | Cas d’usage |
|---|---|---|
| Erreurs de champ | Vérifier la présence d’une classe d’erreur | Validation d’un champ individuel |
| Erreurs de formulaire globales | Surveiller le conteneur d’erreurs | État global du formulaire |
| Messages de réussite | Surveiller les affichages de confirmation | Finalisation de l’envoi |
| États de chargement | Suivre l’état du bouton d’envoi | Indication de traitement |
Conclusion
Points clés à retenir
La méthode waitForFunction de Puppeteer évalue des conditions JavaScript jusqu’à ce qu’elles renvoient true, offrant un contrôle précis des interactions avec les pages dynamiques [3].
Voici quelques avantages clés de waitForFunction :
- Évaluation flexible : gère les fonctions asynchrones pour surveiller des états de page complexes [3].
- Intégration du contexte : permet de transmettre directement des arguments Node.js au contexte du navigateur [3].
- Logique personnalisée : permet une automatisation adaptée à des conditions de page spécifiques [2].
Cette approche est particulièrement utile lorsque les méthodes d’attente standard ne suffisent pas. Par exemple, dans les applications monopage avancées, plusieurs éléments peuvent se charger simultanément ou certains états JavaScript peuvent devoir être confirmés avant de poursuivre.
Puppeteer et Latenode en action
Latenode tire parti de waitForFunction pour améliorer l’automatisation des workflows. En intégrant cette méthode, Latenode a créé un nœud de surveillance personnalisé qui vérifie les statuts des sites web et capture des captures d’écran lorsque certaines conditions ne sont pas satisfaites [7].
Voici un exemple de l’utilisation de waitForFunction par Latenode afin de garantir que les éléments critiques sont entièrement affichés avant de poursuivre :
await page.waitForFunction(() => {
const element = document.querySelector('.tv-lightweight-charts');
return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});
Cet extrait attend qu’un élément portant la classe .tv-lightweight-charts apparaisse non seulement dans le DOM, mais soit également entièrement affiché [2].
Pour obtenir les meilleurs résultats avec Latenode et Puppeteer :
- Définissez des valeurs de délai appropriées à l’aide de
page.setDefaultTimeout(). - Utilisez des blocs
try-catchpour une gestion robuste des erreurs. - Suivez les temps d’exécution afin d’affiner vos conditions d’attente.


