Latenode

Puppeteer: Auf Netzwerk-Inaktivität warten – ein umfassender Leitfaden zu Wartemethoden

Erfahren Sie, wie Sie mit effektiven Wartestrategien in Puppeteer die Zuverlässigkeit und Geschwindigkeit Ihrer Webautomatisierungsskripte verbessern.

7 Min. Lesezeit
Puppeteer-Diagramm mit Netzwerkaktivität und verschiedenen Warteoptionen

Haben Sie Probleme mit Timeouts oder Fehlern bei Puppeteer-Skripten? So beheben Sie sie.

Puppeteer, eine Node.js-Bibliothek zur Steuerung von Chrome, ist leistungsstark für die Webautomatisierung. Dynamische Inhalte und API-gesteuerte Seiten können das Timing jedoch schwierig machen. Mit den richtigen Warte-Strategien funktionieren Ihre Skripte zuverlässig und effizient.

Das Wichtigste im Überblick:

  • waitForSelector(): Wartet darauf, dass Elemente erscheinen, etwa Buttons oder Formulare.
  • waitForNavigation(): Verarbeitet Seitenwechsel und stellt sicher, dass Seiten vollständig geladen werden.
  • waitForNetworkIdle(): Ideal für API-intensive Seiten; wartet, bis alle Netzwerkanfragen abgeschlossen sind.
  • Benutzerdefinierte Bedingungen: Verwenden Sie waitForFunction() für komplexe Fälle wie dynamische Inhalte oder Animationen.

Schnelle Tipps:

  • Passen Sie Timeouts mit page.setDefaultTimeout() an, um langsam ladende Seiten zu verarbeiten.
  • Kombinieren Sie mehrere Wartemethoden mit Promise.all(), um die Zuverlässigkeit zu erhöhen.
  • Debuggen Sie Wartefehler, indem Sie Netzwerkanfragen überwachen oder die Sichtbarkeit von Elementen prüfen.

Beginnen Sie mit diesen Strategien, um Ihre Puppeteer-Skripte schneller, zuverlässiger und besser geeignet für moderne Webanwendungen zu machen.

Wie wartet oder pausiert man für N Sekunden in puppeteer?

Wie Puppeteer Wartevorgänge verarbeitet

Wenn Sie Puppeteer für die Automatisierung einsetzen, ist es entscheidend zu verstehen, wie Wartevorgänge verarbeitet werden, um zuverlässig funktionierende Skripte zu erstellen. Puppeteer verfügt über standardmäßige Timeout-Einstellungen, damit Skripte nicht unbegrenzt hängen bleiben. Für komplexere Fälle müssen diese Einstellungen jedoch möglicherweise angepasst oder durch eigene Strategien ergänzt werden.

Integrierte Timeout-Einstellungen

Puppeteer legt Standard-Timeouts für Aufgaben wie Navigation, Elementauswahl, Netzwerkanfragen, XPath-Abfragen und benutzerdefinierte Funktionen fest. Dadurch wird sichergestellt, dass Ihre Skripte nicht unbegrenzt hängen bleiben, wenn etwas schiefläuft oder zu lange dauert [2].

Sie können diese Standardwerte mit page.setDefaultTimeout(timeout) ändern [2]. Wenn Ihre Anwendung beispielsweise länger braucht, um komplexe Funktionen zu laden, kann ein höheres Timeout verhindern, dass Ihr Skript zu früh abbricht. Diese Standardeinstellungen sind zwar praktisch, stimmen aber nicht immer mit dem Verhalten dynamischer Anwendungen überein.

Herausforderungen bei Standardeinstellungen

Moderne Webanwendungen setzen häufig auf das dynamische Laden von Inhalten, wodurch die standardmäßigen Wartefunktionen von Puppeteer möglicherweise nicht ausreichen. Puppeteer bietet zwei Network-Idle-Bedingungen, um dies zu steuern:

  • networkidle0: Wartet, bis 500 ms lang keine Netzwerkverbindungen bestehen [1].
  • networkidle2: Wartet, bis 500 ms lang nicht mehr als zwei Netzwerkverbindungen bestehen [1].

Diese Bedingungen entsprechen jedoch nicht immer dem Verhalten von Webanwendungen. Häufige Probleme sind:

  • Inhalte werden nach der DOM-Bereitschaft über JavaScript geladen
  • Elemente werden als Reaktion auf API-Aufrufe aktualisiert
  • Infinite Scrolling lädt zusätzliche Inhalte
  • Single-Page-Anwendungen aktualisieren Ansichten dynamisch

Um diese Herausforderungen zu bewältigen, verwenden Sie einen try-catch-Block zur Behandlung von Timeout-Fehlern [2]. So kann Ihr Skript abrupte Fehler vermeiden und bei Bedarf Fallback-Strategien anwenden. Statt auf feste Verzögerungen zu setzen, sollten Sie Wartebedingungen anhand des tatsächlichen Seitenstatus erstellen [3]. Dieser Ansatz ist flexibler und besser für dynamische Umgebungen geeignet.

Die wichtigsten Wartemethoden in Puppeteer

Puppeteer bietet drei zentrale Methoden zur Verarbeitung von Elementerkennung, Seitennavigation und Netzwerkaktivität. Diese Methoden helfen Ihnen, Interaktionen effektiv zu steuern, insbesondere in dynamischen Webumgebungen.

Verwendung von waitForSelector()

Die Methode waitForSelector() pausiert die Ausführung, bis ein bestimmtes Element auf der Seite erscheint. Das ist besonders hilfreich für dynamisch geladene Inhalte in Single-Page-Anwendungen (SPAs).

So können Sie sie verwenden:

// Warten, bis ein Element erscheint
await page.waitForSelector('.button-class');

// Warten, bis das Element sichtbar ist
await page.waitForSelector('.button-class', { visible: true });

// Benutzerdefiniertes Timeout festlegen
await page.waitForSelector('.button-class', { timeout: 5000 });

Diese Methode stellt sicher, dass Ihr Skript nur mit Elementen interagiert, wenn diese bereit sind.

Verwendung von waitForNavigation()

Die Methode waitForNavigation() wurde für Seitenwechsel entwickelt. Sie wartet, bis die Seite nach Ereignissen wie einem Link-Klick oder dem Absenden eines Formulars vollständig geladen ist.

await Promise.all([
  page.waitForNavigation(),
  page.click('.navigation-link')
]);

Sie können das Verhalten mit Optionen anpassen:

OptionBeschreibungAm besten geeignet für
waitUntil: 'load'Wartet, bis das Load-Ereignis der Seite ausgelöst wirdStatische Seiten
waitUntil: 'domcontentloaded'Wartet, bis das DOM vollständig geladen istSchnelle Interaktionen
waitUntil: 'networkidle0'Wartet, bis keine Netzwerkanfragen aktiv sindKomplexe Anwendungen

Diese Flexibilität gewährleistet eine reibungslose Verarbeitung der Navigation in unterschiedlichen Fällen.

Verwendung von waitForNetworkIdle()

Die Option waitForNetworkIdle() eignet sich ideal zur Überwachung der Netzwerkaktivität. Sie wartet, bis das Netzwerk entweder vollständig oder nahezu inaktiv ist.

// Warten, bis alle Netzwerkanfragen abgeschlossen sind
await page.goto(url, { waitUntil: 'networkidle0' });

// Bis zu zwei aktive Verbindungen zulassen, z. B. WebSockets
await page.goto(url, { waitUntil: 'networkidle2' });

Beispiel:

try {
  await page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 30000 });
  await page.waitForSelector('.dynamic-content', { visible: true });
} catch (error) {
  console.error('Timeout beim Laden aufgetreten');
}

Verwenden Sie networkidle0, wenn alle Anfragen vollständig abgeschlossen sein sollen, oder networkidle2, wenn Hintergrundverbindungen aktiv bleiben könnten.

Diese Methoden sind essenziell für zuverlässige Webautomatisierungs-Skripte und sorgen dafür, dass Ihre Interaktionen mit Webseiten konsistent und effizient sind.

sbb-itb-23997f1

Komplexe Warte-Techniken

Manchmal reichen grundlegende Wartemethoden nicht aus. Für komplexere Fälle sind fortgeschrittene Techniken die richtige Wahl.

Benutzerdefinierte Wartebedingungen

Wenn Standard-Selektoren nicht ausreichen, können Sie mit waitForFunction() benutzerdefinierte Wartebedingungen auf Basis des Seitenstatus oder von JavaScript-Ausdrücken definieren.

// Warten, bis eine bestimmte Anzahl an Elementen geladen ist
await page.waitForFunction(() => {
  return document.querySelectorAll('.product-card').length > 5;
});

// Auf dynamische Inhalte warten und ihren Status validieren
await page.waitForFunction(
  (expectedText) => {
    const element = document.querySelector('.status');
    return element && element.innerText.includes(expectedText);
  },
  {},
  'Bereit'
);

Sie können auch mehrere Bedingungen für komplexere Fälle kombinieren:

await page.waitForFunction(() => {
  const isLoaded = document.readyState === 'complete';
  const hasContent = document.querySelector('.content')?.innerHTML.length > 0;
  const noSpinner = !document.querySelector('.loading-spinner');
  return isLoaded && hasContent && noSpinner;
});

Gehen wir noch einen Schritt weiter und verarbeiten mehrere Bedingungen gleichzeitig.

Mehrere Wartemethoden

Bei komplexen Anwendungen müssen Sie häufig gleichzeitig auf mehrere Bedingungen warten. Mit Promise.all() können Sie dies effizient verwalten.

Beispiel für das dynamische Absenden eines Formulars:

// Formularübermittlung mit mehreren Bedingungen verarbeiten
const submitForm = async () => {
  await Promise.all([
    page.waitForNavigation({ waitUntil: 'networkidle0' }),
    page.waitForFunction(() => !document.querySelector('.processing')),
    page.click('#submit-button')
  ]);
};

Race Conditions verarbeiten:

Manchmal müssen Sie fortfahren, sobald die erste Bedingung erfüllt ist. Dafür können Sie Promise.race() verwenden:

// Auf eine Erfolgs- oder Fehlermeldung warten
const waitForResponse = async () => {
  await Promise.race([
    page.waitForSelector('.success-message'),
    page.waitForSelector('.error-message')
  ]);
};

Komplexe Ladeszenarien:

Hier ist ein Beispiel für die Verwaltung dynamisch geladener Inhalte mit mehreren Bedingungen:

const loadDynamicContent = async () => {
  await page.click('.load-more');
  await Promise.all([
    page.waitForFunction(() => {
      return window.scrollY + window.innerHeight >= document.documentElement.scrollHeight;
    }),
    page.waitForSelector('.new-items', { visible: true }),
    page.waitForFunction(() => {
      return document.querySelectorAll('.item').length > 10;
    })
  ]);
};

Mit diesen Techniken können Sie robustere Automatisierungs-Skripte erstellen, die komplexe Webanwendungen mit asynchronen Vorgängen und dynamischen Inhalten verarbeiten.

Wartemethoden beschleunigen

Die Optimierung von Wartemethoden kann die Geschwindigkeit und Zuverlässigkeit von Automatisierungs-Skripten erheblich verbessern. Durch die Kombination intelligenter manueller Techniken mit KI-gestützten Strategien erreichen Sie eine schnellere Ausführung, ohne Stabilität einzubüßen.

Geschwindigkeit vs. Stabilität

Ein entscheidender Faktor bei der Optimierung von Wartemethoden ist das Verständnis dafür, wie Ihre Seite geladen wird. Es ist essenziell, Wartezeiten an das reale Ladeverhalten der Seite anzupassen.

// Standard-Timeout für alle Vorgänge festlegen
page.setDefaultTimeout(30000);

// Effiziente Wartebedingungen verwenden
const waitForContent = async () => {
  try {
    await page.waitForSelector('.content', {
      visible: true,
      timeout: 5000 // Kürzeres Timeout für bestimmte Elemente
    });
  } catch (error) {
    console.error('Timeout beim Laden von Inhalten');
    throw error;
  }
};

Verwenden Sie für vollständige Seitenladevorgänge 'networkidle0' und für dynamische Inhalte 'networkidle2'. So schaffen Sie ein Gleichgewicht zwischen Geschwindigkeit und Zuverlässigkeit.

„Während das Warten auf einen festen Zeitraum eine schlechte Praxis ist, ist es in der Realität schwierig, eine Lösung zu finden, die in allen Fällen gut funktioniert.“ – Dmytro Krasun [4]

Eine weitere Möglichkeit zur Leistungssteigerung besteht darin, nicht essenzielle Ressourcen zu deaktivieren. Für noch höhere Effizienz sollten Sie jedoch KI-gestützte Lösungen in Betracht ziehen.

KI-gestützte Warte-Logik

KI kann die Optimierung von Wartevorgängen auf die nächste Stufe heben, indem sie das Seitenverhalten analysiert und Bedingungen dynamisch anpasst. Tools wie Latenode nutzen KI, um Warte-Strategien präzise abzustimmen.

// Beispiel für KI-optimierte Warte-Logik
const smartWait = async () => {
  await page.waitForFunction(() => {
    const contentReady = document.querySelector('.content')?.offsetHeight > 0;
    const apiLoaded = window._apiData && Object.keys(window._apiData).length > 0;
    const animationsComplete = !document.querySelector('.loading-animation');

    return contentReady && apiLoaded && animationsComplete;
  }, {
    timeout: 15000,
    polling: 'mutation' // Optimierte Polling-Strategie
  });
};

Für komplexere Fälle kann paralleles Warten mit optimierten Timeouts entscheidend sein:

// Paralleles Warten mit Timeout-Optimierung
const optimizedLoad = async () => {
  const timeoutPromise = new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Vorgang hat das Zeitlimit überschritten')), 10000)
  );

  try {
    await Promise.race([
      Promise.all([
        page.waitForSelector('.content'),
        page.waitForFunction(() => window.dataLoaded === true),
        page.waitForNetworkIdle({
          idleTime: 500,
          timeout: 8000
        })
      ]),
      timeoutPromise
    ]);
  } catch (error) {
    console.error('Laden fehlgeschlagen:', error.message);
    throw error;
  }
};

Diese Methoden helfen Ihren Skripten, sich an unterschiedliche Netzwerkbedingungen und Seitenladezeiten anzupassen, und gewährleisten sowohl Geschwindigkeit als auch Zuverlässigkeit.

Probleme bei Wartevorgängen beheben

Damit Ihre Automatisierungs-Skripte reibungslos ausgeführt werden, ist es wichtig, Timeout-Fehler nach der Optimierung der Wartemethoden zu beheben.

Timeouts verwalten

Timeout-Fehler treten auf, wenn das Laden einer Seite länger dauert als erwartet. Standardmäßig setzt Puppeteer ein Timeout von 30 Sekunden, was bei langsamen Internetverbindungen oder umfangreichen Seiten möglicherweise nicht ausreicht.

So können Sie die Timeout-Einstellungen anpassen:

// Globales Timeout für alle Vorgänge festlegen
await page.setDefaultTimeout(60000); // 60 Sekunden

// Spezifisches Timeout für die Navigation festlegen
await page.setDefaultNavigationTimeout(60000); // 60 Sekunden

try {
  await page.waitForSelector('.dynamic-content', {
    visible: true,
    timeout: 10000 // 10 Sekunden
  });
} catch (error) {
  console.error('Timeout beim Warten auf Element:', error.message);
  // Erwägen Sie, hier eine Fallback-Strategie hinzuzufügen
}

Versuchen Sie bei komplexeren Fällen inkrementelle Timeouts. Bei diesem Ansatz wird der Vorgang mit zunehmend längeren Zeitintervallen wiederholt:

const waitWithRetry = async (selector, maxAttempts = 3) => {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      await page.waitForSelector(selector, {
        timeout: 5000 * attempt // Timeout bei jedem Versuch erhöhen
      });
      return true;
    } catch (error) {
      if (attempt === maxAttempts) throw error;
      console.warn(`Versuch ${attempt} fehlgeschlagen, erneuter Versuch...`);
    }
  }
};

Wartefehler finden

Um Wartefehler zu debuggen, nutzen Sie systematische Überwachungstechniken. Zum Beispiel:

// Netzwerkanfragen auf mögliche Timing-Probleme überwachen
await page.setRequestInterception(true);
page.on('request', request => {
  console.log(`${request.method()} ${request.url()}`);
  request.continue();
});

// Prüfen, ob ein Element auf der Seite sichtbar ist
const elementVisibilityCheck = async (selector) => {
  const isVisible = await page.evaluate((sel) => {
    const element = document.querySelector(sel);
    if (!element) return false;

    const style = window.getComputedStyle(element);
    return style.display !== 'none' && 
           style.visibility !== 'hidden' && 
           style.opacity !== '0';
  }, selector);

  return isVisible;
};

Häufige Wartefehler und ihre Lösungen:

FehlertypUrsacheLösung
Navigation TimeoutUmfangreicher SeitenladevorgangTimeout auf 60000 ms erhöhen
Element Not FoundDynamische InhaltewaitForFunction mit einem Mutation Observer verwenden
Network Idle TimeoutMehrere API-AufrufeDie Strategie networkidle2 verwenden
Interaction FailedElementstatusPrüfungen zur Interaktionsfähigkeit des Elements hinzufügen

Hier ist ein robustes Beispiel für die effektive Behandlung von Wartefehlern:

const robustWait = async (page, selector) => {
  try {
    const element = await page.waitForSelector(selector, {
      visible: true,
      timeout: 15000 // 15 Sekunden
    });

    // Sicherstellen, dass das Element interaktiv ist
    await page.waitForFunction(
      (sel) => {
        const el = document.querySelector(sel);
        return el && !el.disabled && el.getBoundingClientRect().height > 0;
      },
      { timeout: 5000 }, // Timeout für zusätzliche Prüfung
      selector
    );

    return element;
  } catch (error) {
    console.error(`Wartefehler: ${error.message}`);
    throw new Error(`Element ${selector} ist nicht bereit`);
  }
};

Mit diesen Strategien können Sie Timeout-Probleme effektiv beheben und debuggen, sodass Ihre Skripte unterschiedliche Situationen zuverlässig verarbeiten.

Fazit

Beim Einsatz von Warte-Strategien in Puppeteer ist das richtige Gleichgewicht zwischen Geschwindigkeit und Stabilität entscheidend. Die Auswahl der passenden Wartemethode sorgt dafür, dass Ihre automatisierten Webinteraktionen reibungslos laufen und zuverlässige Ergebnisse liefern.

Hier ist ein kurzer Überblick über gängige Warte-Strategien und ihre Einsatzbereiche:

Warte-StrategieBester AnwendungsfallWichtigster Vorteil
waitForSelector()Dynamische UI-ElementeBestätigt, dass das Element vor der Nutzung vorhanden ist
waitForNavigation()SeitenwechselHält Ihr Skript mit Seitenänderungen synchron
waitForNetworkIdle()API-intensive SeitenBestätigt, dass alle Netzwerkanfragen abgeschlossen sind
Benutzerdefinierte WartebedingungenKomplexe FälleBietet präzise Kontrolle über das Timing

Bei dynamischen Inhalten funktioniert die Kombination von waitForSelector() mit benutzerdefinierten Wartebedingungen oft besser als das Festhalten an Standard-Timeouts. Dieser Ansatz gibt Ihnen mehr Kontrolle und reduziert die Fehlerwahrscheinlichkeit.

Mit Tools wie Latenode lässt sich die Einrichtung effektiver Warte-Strategien vereinfachen, sodass Sie sowohl Geschwindigkeit als auch Zuverlässigkeit verbessern können. Darüber hinaus können Timeouts mit page.setDefaultTimeout() dazu beitragen, Skriptfehler zu vermeiden und Ihre Automatisierung effizient zu halten.

References

FAQ

Frequently Asked Questions

Verwenden Sie diese Methode bei API-intensiven oder Single-Page-Anwendungen, bei denen Inhalte erst geladen werden, nachdem das DOM bereit ist. networkidle0 wartet, bis 500 ms lang keine Verbindungen mehr bestehen. networkidle2 erlaubt bis zu zwei aktive Verbindungen für Seiten mit Hintergrund-Sockets.

War das hilfreich? Teile es →

Geschrieben von

Vasiliy Datsenko

Leiter des Kundensupports

Vasiliy Datsenko ist Leiter des Kundensupports bei Latenode und ein produktorientierter Autor zum Thema Automatisierung. Seine Arbeit verbindet Kundengespräche, Workflow-Automatisierungsforschung, KI-Anwendungsfälle und praktische Produktschulungen für Teams, die echte Geschäftsprozesse automatisieren möchten.

Autorenprofil →

Faktencheck von

Oleg Zankov

CEO Latenode, No-code-Experte

Mit einer Philosophie, die auf Innovation, Problemlösung und Benutzererfahrung basiert, konzentriere ich mich darauf, Teams zu befähigen, maßgeschneiderte Integrationen zu erstellen und Arbeitsabläufe einfach und effizient zu automatisieren. Mit umfangreicher Erfahrung in den Bereichen Geschäftsentwicklung, Technologieunternehmertum und Softwareentwicklung erkannte ich den Bedarf an einer zugänglicheren, skalierbareren und anpassungsfähigeren Integrationslösung. So entstand Latenode.com. Mit unserer Plattform können Unternehmen die Macht der Technologie nutzen, ohne umfassende Programmierkenntnisse zu benötigen. Leidenschaftlich daran interessiert, eine Zukunft zu fördern, in der Technologie uns dient und nicht umgekehrt, ist es meine Mission, komplexe Prozesse zu vereinfachen. Ich glaube an die Demokratisierung der Technologie und daran, Teams mit den Werkzeugen auszustatten, um in einer zunehmend digitalen Welt zu innovieren, zu wachsen und erfolgreich zu sein.

Autorenprofil →

Weiterlesen