Latenode

Benutzerdefinierte Wartebedingungen mit waitForFunction in Puppeteer

Erweitern Sie Ihre Puppeteer-Skripte mit benutzerdefinierten Wartebedingungen über waitForFunction und sorgen Sie so für zuverlässige Interaktionen mit dynamischen Webinhalten.

7 Min. Lesezeit
Puppeteer-Code mit benutzerdefinierter waitForFunction-Wartebedingung

Sollen Ihre Puppeteer-Skripte dynamische Websites besser verarbeiten? Der Schlüssel dazu: Mit waitForFunction können Sie benutzerdefinierte Wartebedingungen festlegen, damit Ihre Automatisierung auch bei sich ändernden Inhalten reibungslos funktioniert.

Warum waitForFunction verwenden?

  • Timing steuern: Warten Sie, bis bestimmte Bedingungen erfüllt sind, etwa wenn Elemente geladen werden oder sich Text ändert.
  • Dynamische Inhalte verarbeiten: Ideal für moderne, dynamische Websites.
  • Fehler vermeiden: Vermeiden Sie unnötige Verzögerungen oder zu frühe Interaktionen.

So funktioniert es:

  • Schreiben Sie JavaScript-Bedingungen, die true zurückgeben, sobald alles bereit ist.
  • Nutzen Sie Optionen wie die Polling-Frequenz (raf, mutation oder Millisekunden) und Timeouts für eine bessere Performance.
  • Kombinieren Sie DOM-Prüfungen mit API-Antworten für fortgeschrittene Anwendungsfälle.

Beispiel:

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

Wichtige Funktionen:

  • Überwachen Sie die Sichtbarkeit von Elementen, Textinhalte oder benutzerdefinierte Eigenschaften.
  • Kombinieren Sie mehrere Bedingungen für komplexe Workflows.
  • Behandeln Sie Timeouts und Fehler zuverlässig.

Tipp: Nutzen Sie waitForFunction als Ersatz für veraltete sleep-Aufrufe und steigern Sie die Effizienz.

Schneller Überblick:

FunktionZweck
Polling-ModiPrüft Bedingungen über „raf“, „mutation“ oder benutzerdefinierte Intervalle
Benutzerdefinierte BedingungenWartet auf bestimmte DOM-Zustände oder API-Antworten
Timeout-VerwaltungLegt operationsspezifische oder globale Timeouts fest

Mit dieser Methode bleiben Ihre Skripte zuverlässig, effizient und für jede Herausforderung durch dynamische Inhalte gerüstet.

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

Grundlagen von waitForFunction

Die Methode waitForFunction in Puppeteer ermöglicht es Ihnen, benutzerdefinierte Bedingungen festzulegen, auf die Ihre Skripte vor dem Fortfahren warten sollen. So nutzen Sie sie effektiv.

Grundlegende Wartefunktionen schreiben

So erstellen Sie eine einfache Wartefunktion:

// 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'
);

Entscheidend ist, dass Ihre Funktion einen truthy value zurückgeben muss, bevor das Skript fortfahren kann [1].

Sehen wir uns nun an, wie Sie die Funktion für eine bessere Performance konfigurieren.

Funktionsparameter einrichten

Sie können waitForFunction mit einem Optionsobjekt präzise anpassen. Zu den wichtigsten Parametern gehören:

ParameterBeschreibungGängige Werte
pollingWie häufig die Bedingung geprüft wird„raf“, „mutation“ oder Millisekunden
timeoutMaximale WartezeitStandard: 30.000 ms (30 Sekunden)

Polling-Modi [4]:

  1. RequestAnimationFrame („raf“)
    Ideal zur Überwachung von Stiländerungen, da Bedingungen bei jedem Animationsframe geprüft werden.

  2. Mutation Observer („mutation“)
    Nützlich zum Verfolgen von Änderungen in der DOM-Struktur. Prüfungen werden ausgelöst, sobald das DOM aktualisiert wird.

  3. Benutzerdefiniertes Intervall (Millisekunden)
    Dieses Beispiel prüft die Bedingung jede Sekunde:

    await page.waitForFunction(
      () => document.readyState === 'complete',
      { polling: 1000, timeout: 5000 }
    );
    

Wählen Sie den Polling-Modus passend zu Ihren Anforderungen:

  • Verwenden Sie 'raf' für Animationen oder Stilaktualisierungen.
  • Wählen Sie 'mutation' für DOM-bezogene Änderungen.
  • Legen Sie ein benutzerdefiniertes Intervall in Millisekunden für breitere Anwendungsfälle fest.

Benutzerdefinierte Wartebedingungen erstellen

Anzeigestatus von Elementen prüfen

Um zu bestätigen, dass ein Element sichtbar ist, können Sie seine Existenz und Abmessungen prüfen:

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

Dadurch wird sichergestellt, dass das Element vorhanden ist und auf der Seite sichtbare Abmessungen hat. Das ist besonders hilfreich bei dynamischen Inhalten, die Zeit benötigen, um vollständig geladen zu werden [2].

Text und Elementeigenschaften prüfen

Neben visuellen Prüfungen können Sie Textinhalte oder bestimmte Eigenschaften von Elementen überwachen:

// Wait for specific text content
await page.waitForFunction(
    selector => {
        const element = document.querySelector(selector);
        return element && element.textContent.includes('Ready');
    },
    {},
    '.status-message'
);

Für detailliertere Eigenschaftsprüfungen übergeben Sie zusätzliche Argumente:

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
);

Mehrere Wartebedingungen kombinieren

Nachdem Sie einzelne Bedingungen getestet haben, können Sie diese für komplexere Anwendungsfälle kombinieren. Beispiel:

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;
});

Für mehrere Elemente mit unabhängigen Bedingungen verwenden Sie Promise-Kombinationen [5]:

WartemusterAnwendungsfallImplementierung
Alle ElementeAuf mehrere erforderliche Elemente wartenPromise.all()
Beliebiges ElementFortfahren, sobald das erste Element erscheintPromise.race()
Benutzerdefinierte LogikKomplexe bedingte Prüfungen verarbeitenKombinierte Wartefunktionen

Für asynchrone Vorgänge können Sie fortgeschrittene Wartebedingungen erstellen:

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' }
);

Diese Methode kombiniert die Validierung von API-Antworten mit DOM-Elementprüfungen und stellt sicher, dass sowohl die Daten als auch der visuelle Inhalt bereit sind [1].

sbb-itb-23997f1

Fortgeschrittene waitForFunction-Methoden

Komplexe JavaScript-Bedingungen schreiben

Für dynamischere Webanwendungen können Sie waitForFunction nutzen, um detaillierte JavaScript-Bedingungen zu erstellen. Hier ist ein Beispiel:

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
);

Dieses Skript stellt sicher, dass:

  • der Diagramm-Container vorhanden ist.
  • eine Mindestanzahl an Datenpunkten vorhanden ist.
  • alle Datenpunkte sichtbar sind.
  • sich keiner der Punkte im Ladezustand befindet.

Sie können zudem asynchrone Prüfungen mit DOM-Auswertungen für komplexere Anwendungsfälle kombinieren:

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
    }
);

Dieser Ansatz kombiniert DOM-Prüfungen mit einem API-Aufruf, um sicherzustellen, dass sowohl die Benutzeroberfläche als auch das Backend synchron sind.

Timeouts und Fehler behandeln

Die Verwaltung von Timeouts ist bei der Arbeit mit waitForFunction entscheidend. Hier ist ein Beispiel für eine effektive Timeout-Behandlung:

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;
}

Hier ist ein schneller Überblick über Timeout-Strategien:

Timeout-StrategieAnwendungsfallKonfiguration
Standard-TimeoutAllgemeine Vorgängepage.setDefaultTimeout()
Navigation-TimeoutSeitenladevorgängepage.setDefaultNavigationTimeout()
OperationsspezifischDetaillierte PrüfungenDie Option timeout in der Methode verwenden
Unbegrenztes WartenBekannte Verzögerungentimeout: 0

So verbessern Sie die Fehlerbehandlung:

  • Passen Sie die Timeout-Einstellungen an die Komplexität jedes Vorgangs an.
  • Verwenden Sie try-catch-Blöcke, um Fehler zuverlässig abzufangen.
  • Überwachen Sie die Netzwerkaktivität, um Engpässe zu identifizieren.
  • Implementieren Sie Fallback-Aktionen wie das Neuladen der Seite, wenn Timeouts auftreten.
  • Prüfen Sie Selektoren doppelt, um unnötige Verzögerungen zu vermeiden.

Diese Praktiken helfen Ihnen dabei, sicherzustellen, dass Ihre Skripte sowohl zuverlässig als auch effizient sind.

waitForFunction beschleunigen

Tipps für Geschwindigkeit und Ressourcennutzung

Damit waitForFunction effizienter läuft, sollten Sie auf intelligente Warte-Strategien und ein korrektes Ressourcenmanagement setzen. Nutzen Sie die Entwicklerwerkzeuge des Browsers, um Ladezeiten zu messen und präzise Timeouts festzulegen.

// 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;
});

So reduzieren Sie den Ressourcenverbrauch:

  • Blockieren Sie unnötige Assets wie Bilder oder Schriftarten.
  • Verwenden Sie waitForSelector oder waitForFunction statt des veralteten waitForTimeout.
  • Fassen Sie mehrere Prüfungen in einem einzigen evaluate-Aufruf zusammen, um die Kommunikation zwischen Browser und Node zu reduzieren.
StrategiePerformance-AuswirkungBester Anwendungsfall
networkidle2ModeratSeitennavigation
waitForSelectorSchnellPrüfungen einzelner Elemente
waitForFunctionVariabelKomplexe Bedingungen
Kombiniertes evaluateAm schnellstenPrüfungen mehrerer Elemente

Diese Methoden können dabei helfen, häufige Engpässe zu beheben, die im nächsten Abschnitt behandelt werden.

Häufige Probleme beheben

Performance-Probleme entstehen oft durch ineffiziente Warte-Muster. So gehen Sie damit um:

Probleme mit Selektoren
Zu starre Selektoren können zu Fehlern führen. Vereinfachen Sie sie für eine bessere Zuverlässigkeit:

// 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
);

Ressourcenmanagement
Verwalten Sie Ressourcen und vermeiden Sie unnötige Verzögerungen:

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

„Puppeteer verfügt über eine ereignisgesteuerte Architektur, die viele potenzielle Instabilitäten beseitigt. In Puppeteer-Skripten sind keine unsinnigen sleep[undefined]-Aufrufe erforderlich.“ – Puppeteers Readme [6]

Umschließen Sie Warte-Methoden immer mit try...catch-Blöcken, um Fehler zuverlässig zu behandeln und Fallback-Optionen bereitzustellen. Dieser Ansatz stellt sicher, dass Ihre Skripte robust und zuverlässig bleiben.

Häufige Einsatzbereiche für benutzerdefinierte Wartebedingungen

Produktladen in Onlineshops

Für eine präzise Datenerfassung müssen Produkte zuverlässig geladen werden. Verwenden Sie eine benutzerdefinierte Wartebedingung, um die Ausführung anzuhalten, bis Produktartikel vollständig geladen sind:

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

Für mehr Präzision können Sie diesen Ansatz verwenden:

await page.waitForFunction(() => {
    const productDetails = document.querySelector('.product-details');
    return productDetails && 
           productDetails.offsetHeight > 0 && 
           productDetails.querySelector('.inventory-status') !== null;
}, {timeout: 30000});

So wartet Ihr Skript, bis alle erforderlichen Elemente geladen wurden, und verbessert die Zuverlässigkeit der Datenerfassung in E-Commerce-Anwendungsfällen.

Inhalte in modernen Web-Apps laden

Dynamische Web-Apps benötigen oft spezifische Wartebedingungen, um das Laden von Inhalten zu verarbeiten. Sie können beispielsweise warten, bis ein bestimmtes Element vollständig sichtbar wird:

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

Wenn mehrere Bereiche geladen werden müssen, kombinieren Sie Bedingungen wie folgt:

await page.waitForFunction(() => {
    const contentLoaded = document.querySelector('.content').children.length > 0;
    const dataUpdated = document.body.textContent.includes('Last updated:');
    return contentLoaded && dataUpdated;
}, {polling: 1000});

Diese Methode hilft sicherzustellen, dass Ihre Automatisierungsskripte nahtlos mit dynamischen Inhalten interagieren.

Fehlermeldungen in Formularen erkennen

Die Erkennung von Formularfehlern folgt einer ähnlichen Logik wie Sichtbarkeitsprüfungen für Elemente. So können Sie Fehlermeldungen überwachen:

await page.waitForFunction(() => {
    const errorContainer = document.querySelector('.error-messages');
    const hasErrors = errorContainer?.children.length > 0;
    const isVisible = errorContainer?.offsetParent !== null;
    return hasErrors && isVisible;
});

Sie können auch verschiedene Formularvalidierungszustände mit spezifischen Wartebedingungen verfolgen:

ValidierungstypWartebedingungAnwendungsfall
FeldfehlerPrüfen, ob eine Fehlerklasse vorhanden istValidierung einzelner Felder
Formularweite FehlerFehlercontainer überwachenGesamtstatus des Formulars
ErfolgsmeldungenAuf Bestätigungsanzeigen achtenAbschluss der Übermittlung
LadezuständeStatus der Senden-Schaltfläche verfolgenAnzeige der Verarbeitung

Fazit

Wichtigste Erkenntnisse

Die Methode waitForFunction in Puppeteer wertet JavaScript-Bedingungen aus, bis sie true zurückgeben, und bietet damit präzise Kontrolle über dynamische Seiteninteraktionen [3].

Hier sind einige zentrale Vorteile von waitForFunction:

  • Flexible Auswertung: Verarbeitet asynchrone Funktionen zur Überwachung komplexer Seitenzustände [3].
  • Kontextintegration: Ermöglicht die direkte Übergabe von Node.js-Argumenten in den Browserkontext [3].
  • Benutzerdefinierte Logik: Ermöglicht passgenaue Automatisierung auf Grundlage spezifischer Seitenbedingungen [2].

Dieser Ansatz ist besonders hilfreich, wenn Standard-Warte-Methoden nicht ausreichen. Beispielsweise können in fortgeschrittenen Single-Page-Anwendungen mehrere Elemente gleichzeitig geladen werden oder bestimmte JavaScript-Zustände müssen bestätigt werden, bevor es weitergeht.

Puppeteer und Latenode in der Praxis

Latenode nutzt waitForFunction, um die Workflow-Automatisierung zu verbessern. Durch die Integration dieser Methode hat Latenode einen benutzerdefinierten Monitoring-Node erstellt, der Website-Status prüft und Screenshots erfasst, wenn bestimmte Bedingungen nicht erfüllt sind [7].

Hier ist ein Beispiel dafür, wie Latenode waitForFunction verwendet, um sicherzustellen, dass kritische Elemente vollständig gerendert sind, bevor der Workflow fortgesetzt wird:

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

Dieser Ausschnitt wartet darauf, dass ein Element mit der Klasse .tv-lightweight-charts nicht nur im DOM erscheint, sondern auch vollständig gerendert wird [2].

Für optimale Ergebnisse bei der Verwendung von Latenode mit Puppeteer:

  • Legen Sie geeignete Timeout-Werte mit page.setDefaultTimeout() fest.
  • Verwenden Sie try-catch-Blöcke für eine robuste Fehlerbehandlung.
  • Erfassen Sie Ausführungszeiten, um Ihre Wartebedingungen präzise anzupassen.

References

FAQ

Frequently Asked Questions

waitForFunction prüft im Browser-Kontext wiederholt eine JavaScript-Bedingung, bis sie einen wahrheitsgemäßen Wert zurückgibt, und wird dann aufgelöst. Verwenden Sie die Funktion, wenn das standardmäßige waitForSelector für dynamische Inhalte, benutzerdefinierte DOM-Zustände oder kombinierte API- und DOM-Prüfungen nicht ausreicht.

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