Laténode

Optimisation des stratégiesattente dans Puppeteer : Guide complet des méthodesattente

Apprenez des stratégiesattente efficaces dans Puppeteer pour améliorer la fiabilité et la vitesse de vos scriptsautomatisation web.

RaianRaian
Optimisation des stratégiesattente dans Puppeteer : Guide complet des méthodesattente

Aux prises avec Marionnettiste Les scripts expirent ou échouent ? Voici comment résoudre ce problème.

Marionnettiste, un Node.js bibliothèque pour le contrôle Chrome, est puissant pour l'automatisation web. Cependant, le contenu dynamique et les pages pilotées par API peuvent compliquer le timing. Des stratégiesattente appropriées garantissent le fonctionnement fiable et efficace de vos scripts.

Principaux plats à emporter:

  • waitForSelector(): Attend que des éléments apparaissent (par exemple, des boutons ou des formulaires).
  • waitForNavigation(): Gère les transitions de page et assure le chargement complet des pages.
  • waitForNetworkIdle():Idéal pour les pages riches en API, attend que toutes les requêtes réseau soient terminées.
  • Conditions personnalisées: Utilisation waitForFunction() pour des scénarios complexes comme du contenu dynamique ou des animations.

Astuces rapides:

  • Ajustez les délaisattente à l'aide de page.setDefaultTimeout() pour gérer les pages à chargement lent.
  • Combinez plusieurs méthodesattente avec Promise.all() pour une meilleure fiabilité.
  • Déboguez les erreursattente en surveillant les requêtes réseau ou en vérifiant la visibilité des éléments.

Commencez par ces stratégies pour rendre vos scripts Puppeteer plus rapides, plus fiables et mieux adaptés aux applications Web modernes.

Comment attendre / dormir pendant N secondes dans marionnettiste?

Comment le marionnettiste gère l'attente

Lorsque vous utilisez Puppeteer pour l'automatisation, il est essentiel de comprendre comment il gère l'attente pour créer des scripts fiables. Puppeteer inclut des paramètres de délaiattente par défaut pour éviter que les scripts ne se bloquent indéfiniment, mais ces paramètres peuvent nécessiter un ajustement ou des stratégies personnalisées pour les scénarios plus complexes.

Paramètres de délaiexpiration intégrés

Puppeteer définit des délaisexpiration par défaut pour gérer des tâches telles que la navigation, la sélectionéléments, les requêtes réseau, les requêtes XPath et les fonctions personnalisées. Cela garantit que vos scripts ne se bloquent pas indéfiniment en cas de problème ou de durée excessive. [2].

Vous pouvez modifier ces valeurs par défaut avec page.setDefaultTimeout(timeout) [2]Par exemple, si le chargement de fonctionnalités complexes par votre application prend plus de temps, augmenter le délaiexpiration peut éviter que votre script ne s'arrête trop tôt. Bien que pratiques, ces paramètres par défaut ne sont pas toujours adaptés au comportement des applications dynamiques.

Défis liés aux paramètres par défaut

Les applications web modernes reposent souvent sur le chargement dynamique du contenu, ce qui peut rendre les mécanismesattente par défaut de Puppeteer insuffisants. Puppeteer propose deux conditionsinactivité réseau pour gérer ce problème :

  • networkidle0: Attend qu'il n'y ait plus de connexion réseau pendant 500 ms [1].
  • networkidle2: Attend qu'il n'y ait plus de 2 connexions réseau pendant 500 ms [1].

Cependant, ces conditions ne correspondent pas toujours au comportement des applications web. Les problèmes courants incluent :

  • Chargement du contenu via JavaScript une fois le DOM prêt
  • Mise à jour des éléments en réponse aux appelsAPI
  • Chargement de contenu supplémentaire par défilement infini
  • Applications monopage mettant à jour dynamiquement les vues

Pour relever ces défis, essayez d’utiliser un try-catch bloc pour gérer les erreurs de timeout [2]Cela permet à votre scriptéviter les échecs soudains etappliquer des stratégies de secours si nécessaire. Au lieu de vous fier à des délais fixes, envisagez de créer des conditionsattente basées sur l'état réel de la page. [3]Cette approche est plus flexible et mieux adaptée aux environnements dynamiques.

Principales méthodesattente dans Puppeteer

Puppeteer propose trois méthodes clés pour gérer la détection des éléments, la navigation dans les pages et l'activité réseau. Ces méthodes permettent de gérer efficacement les interactions, notamment dans les environnements web dynamiques.

L'utilisation de waitForSelector()

L'espace waitForSelector() La méthode suspend l'exécution jusqu'à l'apparitionun élément spécifique sur la page. Ceci est particulièrement utile pour le contenu chargé dynamiquement dans les applications monopage (SPA).

Voici comment vous pouvez l'utiliser:

<span class="hljs-comment">// Wait for an element to appear</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.button-class'</span>);

<span class="hljs-comment">// Wait for the element to be visible</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.button-class'</span>, { <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span> });

<span class="hljs-comment">// Set a custom timeout</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.button-class'</span>, { <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span> });

Cette méthode garantit que votre script interagit avec les éléments uniquement lorsqu'ils sont prêts.

L'utilisation de waitForNavigation()

L'espace waitForNavigation() La méthode est conçue pour gérer les transitions entre les pages. Elle attend que la page soit complètement chargée après des événements tels qu'un clic sur un lien ou l'envoiun formulaire.

<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-string">'.navigation-link'</span>)
]);

Vous pouvez personnaliser son comportement avec des options :

OptionDescriptionIdéal pour
attendre jusqu'à : 'chargement'Attend que l'événement de chargement de la page se déclenchePages statiques
waitUntil: 'domcontentloaded'Attend que le DOM soit entièrement chargéInteractions rapides
waitUntil: 'networkidle0'Attend qu'aucune demande réseau ne soit activeApplications complexes

Cette flexibilité garantit une gestion fluide de la navigation pour différents scénarios.

L'utilisation de waitForNetworkIdle()

L'espace waitForNetworkIdle() Cette option est idéale pour surveiller l'activité du réseau. Elle attend que le réseau soit complètement inactif ou presque.

<span class="hljs-comment">// Wait for all network requests to finish</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-comment">// Allow up to 2 active connections (e.g., WebSockets)</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">'networkidle2'</span> });

Par exemple :

<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForNavigation</span>({ <span class="hljs-attr">waitUntil</span>: <span class="hljs-string">'networkidle0'</span>, <span class="hljs-attr">timeout</span>: <span class="hljs-number">30000</span> });
  <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.dynamic-content'</span>, { <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</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">'Loading timeout occurred'</span>);
}

Utilisez le networkidle0 pour compléter la demande ou networkidle2 dans les cas où les connexions en arrière-plan peuvent rester actives.

Ces méthodes sont essentielles pour créer des scripts d’automatisation Web fiables, garantissant que vos interactions avec les pages Web sont cohérentes et efficaces.

sbb-itb-23997f1

Techniquesattente complexes

Parfois, les méthodesattente de base ne suffisent pas. Pour les scénarios plus complexes, des techniques avancées sont la solution.

Conditionsattente personnalisées

Lorsque les sélecteurs standards ne suffisent pas, vous pouvez utiliser waitForFunction() pour définir des conditionsattente personnalisées en fonction de l'état de la page ou des expressions JavaScript.

<span class="hljs-comment">// Wait for a specific number of elements to load</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForFunction</span>(<span class="hljs-function">() =></span> {
  <span class="hljs-keyword">return</span> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'.product-card'</span>).<span class="hljs-property">length</span> > <span class="hljs-number">5</span>;
});

<span class="hljs-comment">// Wait for dynamic content and validate its state</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForFunction</span>(
  <span class="hljs-function">(<span class="hljs-params">expectedText</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">'.status'</span>);
    <span class="hljs-keyword">return</span> element && element.<span class="hljs-property">innerText</span>.<span class="hljs-title function_">includes</span>(expectedText);
  },
  {},
  <span class="hljs-string">'Ready'</span>
);

Vous pouvez également combiner plusieurs conditions pour des scénarios plus complexes :

<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForFunction</span>(<span class="hljs-function">() =></span> {
  <span class="hljs-keyword">const</span> isLoaded = <span class="hljs-variable language_">document</span>.<span class="hljs-property">readyState</span> === <span class="hljs-string">'complete'</span>;
  <span class="hljs-keyword">const</span> hasContent = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.content'</span>)?.<span class="hljs-property">innerHTML</span>.<span class="hljs-property">length</span> > <span class="hljs-number">0</span>;
  <span class="hljs-keyword">const</span> noSpinner = !<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.loading-spinner'</span>);
  <span class="hljs-keyword">return</span> isLoaded && hasContent && noSpinner;
});

Allons maintenant plus loin en gérant plusieurs conditions simultanément.

Plusieurs méthodesattente

Pour les applications complexes, il est souvent nécessaireattendre plusieurs conditions simultanément. Promise.all() peut aider à les gérer efficacement.

Exemple de soumission de formulaire dynamique :

<span class="hljs-comment">// Handle form submission with multiple conditions</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">submitForm</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></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_">waitForFunction</span>(<span class="hljs-function">() =></span> !<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.processing'</span>)),
    page.<span class="hljs-title function_">click</span>(<span class="hljs-string">'#submit-button'</span>)
  ]);
};

Gestion des conditions de course :

Parfois, il est nécessaire de procéder dès que la première condition est remplie. Pour cela, vous pouvez utiliser Promise.race():

<span class="hljs-comment">// Wait for either a success or error message</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">waitForResponse</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></span>) => {
  <span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">race</span>([
    page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.success-message'</span>),
    page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.error-message'</span>)
  ]);
};

Scénarios de chargement complexes :

Voici un exemple de gestion du chargement de contenu dynamique avec plusieurs conditions :

<span class="hljs-keyword">const</span> <span class="hljs-title function_">loadDynamicContent</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></span>) => {
  <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">click</span>(<span class="hljs-string">'.load-more'</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_">waitForFunction</span>(<span class="hljs-function">() =></span> {
      <span class="hljs-keyword">return</span> <span class="hljs-variable language_">window</span>.<span class="hljs-property">scrollY</span> + <span class="hljs-variable language_">window</span>.<span class="hljs-property">innerHeight</span> >= <span class="hljs-variable language_">document</span>.<span class="hljs-property">documentElement</span>.<span class="hljs-property">scrollHeight</span>;
    }),
    page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.new-items'</span>, { <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span> }),
    page.<span class="hljs-title function_">waitForFunction</span>(<span class="hljs-function">() =></span> {
      <span class="hljs-keyword">return</span> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">'.item'</span>).<span class="hljs-property">length</span> > <span class="hljs-number">10</span>;
    })
  ]);
};

Ces techniques vous aident à créer des scripts d’automatisation plus puissants, capables de gérer des applications Web complexes avec des opérations asynchrones et du contenu dynamique.

Rendre les méthodesattente plus rapides

L'amélioration des méthodesattente peut considérablement améliorer la vitesse et la fiabilité des scriptsautomatisation. En combinant des techniques manuelles plus intelligentes avec des stratégies basées sur l'IA, vous pouvez accélérer l'exécution sans compromettre la stabilité.

Vitesse vs stabilité

Un facteur clé pour optimiser les méthodesattente est de comprendre le fonctionnement de votre page. Il est essentieladapter les tempsattente au comportement réel de la page.

<span class="hljs-comment">// Set a default timeout for all operations</span>
page.<span class="hljs-title function_">setDefaultTimeout</span>(<span class="hljs-number">30000</span>);

<span class="hljs-comment">// Use efficient wait conditions</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">waitForContent</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></span>) => {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.content'</span>, {
      <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span> <span class="hljs-comment">// Shorter timeout for specific elements</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">'Content load timeout'</span>);
    <span class="hljs-keyword">throw</span> error;
  }
};

Pour des chargements de page complets, utilisez 'networkidle0', et pour le contenu dynamique, utilisez 'networkidle2'Cela équilibre la vitesse et la fiabilité.

« Bien qu'attendre une période déterminée soit une mauvaise pratique, dans le monde réel, il est difficile de trouver une solution qui fonctionne bien dans tous les cas. » – Dmytro Krasun [4]

Une autre façonaméliorer les performances consiste à désactiver les ressources non essentielles. Cependant, pour une efficacité encore plus grande, envisagez des solutions basées sur l'IA.

Logiqueattente alimentée par l'IA

L'IA peut propulser l'optimisation de l'attente à un niveau supérieur en analysant le comportement des pages et en ajustant les conditions de manière dynamique. Des outils comme Laténode utiliser l’IA pour affiner les stratégies d’attente.

<span class="hljs-comment">// AI-enhanced wait logic example</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">smartWait</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></span>) => {
  <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForFunction</span>(<span class="hljs-function">() =></span> {
    <span class="hljs-keyword">const</span> contentReady = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.content'</span>)?.<span class="hljs-property">offsetHeight</span> > <span class="hljs-number">0</span>;
    <span class="hljs-keyword">const</span> apiLoaded = <span class="hljs-variable language_">window</span>.<span class="hljs-property">_apiData</span> && <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(<span class="hljs-variable language_">window</span>.<span class="hljs-property">_apiData</span>).<span class="hljs-property">length</span> > <span class="hljs-number">0</span>;
    <span class="hljs-keyword">const</span> animationsComplete = !<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">'.loading-animation'</span>);

    <span class="hljs-keyword">return</span> contentReady && apiLoaded && animationsComplete;
  }, {
    <span class="hljs-attr">timeout</span>: <span class="hljs-number">15000</span>,
    <span class="hljs-attr">polling</span>: <span class="hljs-string">'mutation'</span> <span class="hljs-comment">// Optimized polling strategy</span>
  });
};

Pour les scénarios plus complexes, l'attente parallèle avec des délaisattente optimisés peut changer la donne :

<span class="hljs-comment">// Parallel waiting with timeout optimization</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">optimizedLoad</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params"></span>) => {
  <span class="hljs-keyword">const</span> timeoutPromise = <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">10000</span>)
  );

  <span class="hljs-keyword">try</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 class_">Promise</span>.<span class="hljs-title function_">all</span>([
        page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.content'</span>),
        page.<span class="hljs-title function_">waitForFunction</span>(<span class="hljs-function">() =></span> <span class="hljs-variable language_">window</span>.<span class="hljs-property">dataLoaded</span> === <span class="hljs-literal">true</span>),
        page.<span class="hljs-title function_">waitForNetworkIdle</span>({
          <span class="hljs-attr">idleTime</span>: <span class="hljs-number">500</span>,
          <span class="hljs-attr">timeout</span>: <span class="hljs-number">8000</span>
        })
      ]),
      timeoutPromise
    ]);
  } <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">'Loading failed:'</span>, error.<span class="hljs-property">message</span>);
    <span class="hljs-keyword">throw</span> error;
  }
};

Ces méthodes aident vos scripts à s’adapter à diverses conditions de réseau et à différents temps de chargement de pages, garantissant à la fois vitesse et fiabilité.

Résoudre les problèmesattente

Pour garantir le bon fonctionnement de vos scriptsautomatisation, il est important de traiter les erreurs de délaiattente après avoir optimisé les méthodesattente.

Gestion des délaisattente

Des erreurs de délaiattente se produisent lorsqu'une page met plus de temps à charger que prévu. Par défaut, Puppeteer définit un délaiattente de 30 secondes, ce qui peut être insuffisant pour les connexions Internet lentes ou les pages chargées.

Voici comment vous pouvez ajuster les paramètres de délai d’expiration :

<span class="hljs-comment">// Set a global timeout for all operations</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setDefaultTimeout</span>(<span class="hljs-number">60000</span>); <span class="hljs-comment">// 60 seconds</span>

<span class="hljs-comment">// Set a specific timeout for navigation</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setDefaultNavigationTimeout</span>(<span class="hljs-number">60000</span>); <span class="hljs-comment">// 60 seconds</span>

<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForSelector</span>(<span class="hljs-string">'.dynamic-content'</span>, {
    <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">timeout</span>: <span class="hljs-number">10000</span> <span class="hljs-comment">// 10 seconds</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">'Element wait timeout:'</span>, error.<span class="hljs-property">message</span>);
  <span class="hljs-comment">// Consider adding a fallback strategy here</span>
}

Pour les scénarios plus complexes, essayez les délaisexpiration incrémentiels. Cette approche permet de relancer l'opération à intervalles de temps croissants :

<span class="hljs-keyword">const</span> <span class="hljs-title function_">waitWithRetry</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params">selector, maxAttempts = <span class="hljs-number">3</span></span>) => {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> attempt = <span class="hljs-number">1</span>; attempt <= maxAttempts; attempt++) {
    <span class="hljs-keyword">try</span> {
      <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> * attempt <span class="hljs-comment">// Increase timeout with each attempt</span>
      });
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">if</span> (attempt === maxAttempts) <span class="hljs-keyword">throw</span> error;
      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">warn</span>(<span class="hljs-string">`Attempt <span class="hljs-subst">${attempt}</span> failed, retrying...`</span>);
    }
  }
};

Rechercheerreursattente

Pour corriger les erreursattente, utilisez des techniques de surveillance systématique. Par exemple :

<span class="hljs-comment">// Monitor network requests for potential timing issues</span>
<span class="hljs-keyword">await</span> page.<span class="hljs-title function_">setRequestInterception</span>(<span class="hljs-literal">true</span>);
page.<span class="hljs-title function_">on</span>(<span class="hljs-string">'request'</span>, <span class="hljs-function"><span class="hljs-params">request</span> =></span> {
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`<span class="hljs-subst">${request.method()}</span> <span class="hljs-subst">${request.url()}</span>`</span>);
  request.<span class="hljs-title function_">continue</span>();
});

<span class="hljs-comment">// Check if an element is visible on the page</span>
<span class="hljs-keyword">const</span> <span class="hljs-title function_">elementVisibilityCheck</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params">selector</span>) => {
  <span class="hljs-keyword">const</span> isVisible = <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">evaluate</span>(<span class="hljs-function">(<span class="hljs-params">sel</span>) =></span> {
    <span class="hljs-keyword">const</span> element = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(sel);
    <span class="hljs-keyword">if</span> (!element) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

    <span class="hljs-keyword">const</span> style = <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">getComputedStyle</span>(element);
    <span class="hljs-keyword">return</span> style.<span class="hljs-property">display</span> !== <span class="hljs-string">'none'</span> && 
           style.<span class="hljs-property">visibility</span> !== <span class="hljs-string">'hidden'</span> && 
           style.<span class="hljs-property">opacity</span> !== <span class="hljs-string">'0'</span>;
  }, selector);

  <span class="hljs-keyword">return</span> isVisible;
};

Erreurs d’attente courantes et leurs solutions :

TypeerreurCausesSolution
Délaiexpiration de la navigationChargement de page importantAugmenter le délaiattente à 60000 XNUMX ms
Élément introuvableContenu dynamiqueUtilisez waitForFunction avec un observateur de mutations
Délaiinactivité du réseauAppels API multiplesUtilisez la stratégie networkidle2
Échec de l'interactionÉtat de l'élémentAjouter des vérifications pour l'interactivité des éléments

Voici un exemple robuste pour gérer efficacement les erreurs d’attente :

<span class="hljs-keyword">const</span> <span class="hljs-title function_">robustWait</span> = <span class="hljs-keyword">async</span> (<span class="hljs-params">page, selector</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>(selector, {
      <span class="hljs-attr">visible</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">timeout</span>: <span class="hljs-number">15000</span> <span class="hljs-comment">// 15 seconds</span>
    });

    <span class="hljs-comment">// Ensure the element is interactive</span>
    <span class="hljs-keyword">await</span> page.<span class="hljs-title function_">waitForFunction</span>(
      <span class="hljs-function">(<span class="hljs-params">sel</span>) =></span> {
        <span class="hljs-keyword">const</span> el = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(sel);
        <span class="hljs-keyword">return</span> el && !el.<span class="hljs-property">disabled</span> && el.<span class="hljs-title function_">getBoundingClientRect</span>().<span class="hljs-property">height</span> > <span class="hljs-number">0</span>;
      },
      { <span class="hljs-attr">timeout</span>: <span class="hljs-number">5000</span> }, <span class="hljs-comment">// Additional check timeout</span>
      selector
    );

    <span class="hljs-keyword">return</span> element;
  } <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">`Wait error: <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_">Error</span>(<span class="hljs-string">`Element <span class="hljs-subst">${selector}</span> isn't ready`</span>);
  }
};

Ces stratégies peuvent vous aider à résoudre et à déboguer efficacement les problèmes de délaiattente, garantissant que vos scripts gèrent différents scénarios avec élégance.

Conclusion

Trouver le juste équilibre entre rapidité et stabilité est essentiel pour utiliser des stratégiesattente dans Puppeteer. Choisir la bonne méthodeattente garantit le bon déroulement de vos interactions web automatisées et la fiabilité de vos résultats.

Voici un aperçu rapide des stratégies d’attente courantes et du moment où les utiliser :

StratégieattenteMeilleur casutilisationAvantage clé
attendreSélecteur()Élémentsinterface utilisateur dynamiquesConfirme que l'élément est présent avant utilisation
attendre la navigation()Transitions de pagesMaintient votre script synchronisé avec les changements de page
attendre que le réseau soit inactif()Pages riches en APIConfirme que toutes les demandes réseau sont terminées
Conditionsattente personnaliséesScénarios complexesOffre un contrôle précis du timing

Pour un contenu dynamique, combinant waitForSelector() L'utilisation de conditionsattente personnalisées est souvent plus efficace que les délaisattente par défaut. Cette approche vous offre un meilleur contrôle et réduit les risqueserreurs.

L'utilisationoutils comme Latenode peut simplifier la mise en place de stratégiesattente efficaces, améliorant ainsi la rapidité et la fiabilité. De plus, la définition de délaisattente avec page.setDefaultTimeout() peut aider à éviter les échecs de script tout en gardant votre automatisation efficace.

articles similaires

Raian

Chercheur, expert Nocode

Détails de l'auteur →