Une plateforme low-code alliant la simplicité du no-code à la puissance du full-code 🚀
Commencez gratuitement
Conditions d'attente personnalisées avec waitForFunction dans Puppeteer
21 mars 2025
9
min lire

Conditions d'attente personnalisées avec waitForFunction dans Puppeteer

Georges Miloradovitch
Chercheur, rédacteur et intervieweur de cas d'utilisation
Table des matières

Voulez votre Marionnettiste des scripts pour mieux gérer les sites Web dynamiques ? Voici la clé : waitForFunction vous permet de définir des règles d'attente personnalisées pour garantir que votre automatisation fonctionne de manière transparente avec un contenu changeant.

Pourquoi utiliser waitForFunction?

  • Synchronisation du contrôle:Attendez que des conditions spécifiques soient remplies (par exemple, le chargement des éléments, les modifications du texte).
  • Gérer le contenu dynamique:Parfait pour les sites Web modernes et dynamiques.
  • Éviter les erreurs: Évitez les retards inutiles ou les interactions prématurées.

Comment ça fonctionne

  • Écrire des conditions JavaScript qui renvoient true quand prêt
  • Utilisez des options telles que la fréquence d'interrogation (raf, mutation, ou millisecondes) et des délais d'attente pour de meilleures performances.
  • Combinez les vérifications DOM avec les réponses API pour les scénarios avancés.

Mise en situation :

await page.waitForFunction(
  () => document.querySelector('.status').textContent === 'Ready'
);

Caractéristiques Clés

  • Surveillez la visibilité des éléments, le contenu du texte ou les propriétés personnalisées.
  • Combinez plusieurs conditions pour des flux de travail complexes.
  • Gérez les délais d’attente et les erreurs avec élégance.

Conseil : Utilisation waitForFunction pour remplacer les obsolètes sleep appels et améliorer l'efficacité.

Description rapide:

Fonctionnalité Ce qu'il fait
Modes de sondage Vérifie les conditions via 'raf', 'mutation', ou intervalles personnalisés
Conditions personnalisées Attendre des états DOM spécifiques ou des réponses API
Gestion des délais d'attente Définir des délais d'expiration spécifiques à l'opération ou globaux

Cette méthode garantit que vos scripts sont fiables, efficaces et prêts à relever tout défi de contenu dynamique.

Comment attendre / dormir pendant N secondes dans marionnettiste?

marionnettiste

Notions de base sur waitForFunction

Le waitForFunction La méthode Puppeteer vous permet de définir des conditions personnalisées pour l'attente de vos scripts avant leur exécution. Voici comment l'utiliser efficacement.

Comment écrire des fonctions d'attente de base

Voici une manière simple de 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'
);

La clé ici est que votre fonction doit renvoyer une valeur véridique avant que le script puisse avancer.

Voyons maintenant comment le configurer pour de meilleures performances.

Configuration des paramètres de fonction

Vous pouvez affiner waitForFunction en passant un objet d'options. Les paramètres clés incluent :

Paramètre Description Valeurs communes
vote À quelle fréquence la condition est-elle vérifiée « raf », « mutation » ou millisecondes
temps mort Temps d'attente maximum Par défaut : 30,000 30 ms (XNUMX secondes)

Modes de sondage:

  1. RequestAnimationFrame ('raf')
    Idéal pour surveiller les changements de style, car il vérifie les conditions pendant chaque image d'animation.
  2. Observateur de mutation (« mutation »)
    Utile pour suivre les modifications dans la structure du DOM. Il déclenche des vérifications à chaque mise à jour du DOM.
  3. Intervalle personnalisé (millisecondes)
    Par exemple, cela vérifie la condition toutes les secondes :
    await page.waitForFunction(
      () => document.readyState === 'complete',
      { polling: 1000, timeout: 5000 }
    );
    

Choisissez le mode de sondage en fonction de vos besoins :

  • Utilisez 'raf' pour des animations ou des mises à jour de style.
  • Opter pour 'mutation' pour les modifications liées au DOM.
  • Définissez un intervalle personnalisé (millisecondes) pour des cas d’utilisation plus larges.

Création de règles d'attente personnalisées

Vérification de l'état d'affichage des éléments

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 que ses dimensions sont visibles sur la page. C'est particulièrement utile pour contenu dynamique cela prend du temps à charger correctement.

Tester les propriétés du texte et des éléments

Au-delà des contrôles visuels, vous pouvez surveiller le contenu du texte ou les 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

Une fois les conditions individuelles testées, vous pouvez les combiner pour créer des scénarios 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 avec des conditions indépendantes, utilisez Promise combinaisons:

Modèle d'attente Case Study Implantation
Tous les éléments Attendre plusieurs éléments requis Promise.all()
Tout élément Continuer lorsque le premier élément apparaît Promise.race()
Logique personnalisée Gérer des contrôles conditionnels 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 Validation de la réponse de l'API avec Vérifications des éléments DOM, en veillant à ce que les données et le contenu visuel soient prêts.

sbb-itb-23997f1

Méthodes waitForFunction avancées

Écrire des conditions JavaScript complexes

Pour des applications Web plus dynamiques, vous pouvez utiliser waitForFunction pour 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 assure :

  • Le conteneur de graphique existe.
  • Un nombre minimum de points de données est présent.
  • Tous les points de données sont visibles.
  • Aucun des points n'est en état de chargement.

Vous pouvez également combiner des vérifications asynchrones avec des évaluations DOM pour des scénarios 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 DOM avec un appel API pour garantir que l'interface utilisateur et le backend sont synchronisés.

Gestion des délais d'attente et des erreurs

La gestion des délais d'attente est cruciale lorsque l'on travaille avec waitForFunctionVoici un exemple de gestion efficace des délais d'attente :

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 bref aperçu des stratégies de temporisation :

Stratégie de temporisation Case Study Configuration
Délai d'expiration par défaut Opérations générales page.setDefaultTimeout()
Délai d'expiration de la navigation Chargements de pages page.setDefaultNavigationTimeout()
Spécifique à l'opération Contrôles détaillés Utilisez l'option timeout option dans la méthode
Attente infinie Retards connus timeout: 0

Pour améliorer la gestion des erreurs :

  • Ajustez les paramètres de délai d’expiration en fonction de la complexité de chaque opération.
  • Utilisez try-catch blocs pour récupérer gracieusement des erreurs.
  • Surveillez l’activité du réseau pour identifier les goulots d’étranglement.
  • Implémentez des actions de secours, comme le rechargement de la page, lorsque des délais d'attente se produisent.
  • Vérifiez deux fois les sélecteurs pour éviter des retards inutiles.

Ces pratiques contribueront à garantir que vos scripts sont à la fois fiables et efficaces.

Accélérer l'exécution de waitForFunction

Conseils sur la vitesse et les ressources

Pour obtenir waitForFunction Pour une meilleure efficacité, privilégiez des stratégies d'attente intelligentes et une gestion optimale des ressources. Utilisez les outils de développement de navigateur pour mesurer les temps de chargement et définir des délais d'expiration 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 comme les images ou les polices.
  • Utilisez waitForSelector or waitForFunction au lieu d'être obsolète waitForTimeout.
  • Combinez plusieurs chèques en un seul evaluate appel pour réduire la communication entre le navigateur et le nœud.
de Marketing Impact sur les performances Meilleur cas d'utilisation
networkidle2 Modérée Navigation de page
waitForSelector Rapide Vérifications d'éléments uniques
waitForFunction Variable Conditions complexes
Combiné evaluate Résultats des tests Vérifications d'éléments multiples

Ces méthodes peuvent aider à résoudre les goulots d’étranglement courants, qui sont abordés dans la section suivante.

Résoudre les problèmes courants

Les problèmes de performance proviennent souvent de modes d'attente inefficaces. Voici comment les résoudre :

Problèmes de sélection
Des sélecteurs trop rigides peuvent entraîner des pannes. Simplifiez-les pour une meilleure 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 retards inutiles :

try {
    await page.waitForFunction(
        () => document.readyState === 'complete' &&
              performance.now() > 1000
    );
} catch (error) {
    console.error('Page load timeout:', error.message);
}

Puppeteer possède une architecture pilotée par événements, ce qui élimine de nombreuses failles potentielles. Il n'y a pas besoin de mal. sleep[undefined] appels dans les scripts du marionnettiste." - Lisez-moi du marionnettiste

Enveloppez toujours les méthodes d'attente dans try...catch Des blocs pour gérer les erreurs efficacement et fournir des options de secours. Cette approche garantit la robustesse et la fiabilité de vos scripts.

Utilisations courantes des règles d'attente personnalisées

Chargement des produits de la boutique en ligne

Il est essentiel de s'assurer que les produits se chargent correctement pour collecter des données précises. Utilisez une règle d'attente personnalisée pour suspendre l'exécution jusqu'à ce que les éléments du produit soient entièrement chargés :

await page.waitForFunction(() => {
    const products = document.querySelectorAll('.product-card');
    return products.length > 0 && all images and prices fully load;
});

Pour plus 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 que tous les éléments nécessaires soient chargés, améliorant ainsi la fiabilité de la collecte de données dans les scénarios de commerce électronique.

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 soit 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 ceci :

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 transparente avec le contenu dynamique.

Détection des messages d'erreur de formulaire

La détection des erreurs de formulaire utilise une logique similaire à celle des contrôles 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 de formulaire à l'aide de conditions d'attente spécifiques :

Type de validation Condition d'attente Case Study
Erreurs de terrain Vérifier la présence d'une classe d'erreur Validation individuelle des champs
Erreurs à l'échelle du formulaire Surveiller le conteneur d'erreurs État général de la forme
Messages de réussite Soyez attentif aux affichages de confirmation Achèvement de la soumission
États de chargement Suivre l'état du bouton d'envoi Indication de traitement

Conclusion

Faits marquants

Le waitForFunction La méthode dans Puppeteer évalue les conditions JavaScript jusqu'à ce qu'elles renvoient true, offrant un contrôle précis sur les interactions dynamiques des pages.

Voici quelques avantages clés de l’utilisation waitForFunction:

  • Évaluation flexible: Gère les fonctions asynchrones pour surveiller les états de page complexes.
  • Intégration du contexte: Permet le passage direct des arguments Node.js dans le contexte du navigateur.
  • Logique personnalisée: Permet une automatisation personnalisée en fonction des conditions de page spécifiques.

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 doivent être confirmés avant de poursuivre.

Marionnettiste et Laténode en action

Laténode

Latenode profite de waitForFunction Pour améliorer l'automatisation des flux de travail. En intégrant cette méthode, Latenode a créé un nœud de surveillance personnalisé qui vérifie l'état des sites web et effectue des captures d'écran lorsque certaines conditions ne sont pas remplies.

Voici un exemple de la façon dont Latenode utilise waitForFunction pour garantir que les éléments critiques sont entièrement rendus avant de continuer :

await page.waitForFunction(() => {
    const element = document.querySelector('.tv-lightweight-charts');
    return element && element.offsetHeight > 0 && element.offsetWidth > 0;
});

Cet extrait attend un élément avec la classe .tv-lightweight-charts pour non seulement apparaître dans le DOM mais aussi être entièrement rendu.

Pour de meilleurs résultats lors de l'utilisation de Latenode avec Puppeteer :

  • Définissez des valeurs de délai d'expiration appropriées à l'aide de page.setDefaultTimeout().
  • Utilisez try-catch blocs pour une gestion robuste des erreurs.
  • Suivez les temps d’exécution pour affiner vos conditions d’attente.

À lire également

Blogs connexes

Cas d'utilisation

Soutenu par