Eine Low-Code-Plattform, die die Einfachheit von No-Code mit der Leistung von Full-Code verbindet 🚀
Jetzt kostenlos starten
Benutzerdefinierte Wartebedingungen mit waitForFunction in Puppeteer
21. März 2025
9
min lesen

Benutzerdefinierte Wartebedingungen mit waitForFunction in Puppeteer

Georgi Miloradowitsch
Forscher, Texter und Usecase-Interviewer
Inhaltsverzeichnis

Möchte Dein Puppenspieler Skripte, um dynamische Websites besser zu handhaben? Hier ist der Schlüssel: waitForFunction ermöglicht Ihnen die Definition benutzerdefinierter Warteregeln um sicherzustellen, dass Ihre Automatisierung reibungslos mit sich ändernden Inhalten funktioniert.

Warum verwenden waitForFunction?

  • Kontrollieren Sie das Timing: Warten Sie, bis bestimmte Bedingungen erfüllt sind (z. B. Elemente geladen, Text geändert).
  • Umgang mit dynamischem Inhalt: Perfekt für moderne, dynamische Websites.
  • Fehler vermeiden: Vermeiden Sie unnötige Verzögerungen oder vorzeitige Interaktionen.

So funktioniert es:

  • Schreiben Sie JavaScript-Bedingungen, die true wenn bereit.
  • Verwenden Sie Optionen wie die Abfragehäufigkeit (raf, mutation, oder Millisekunden) und Timeouts für eine bessere Leistung.
  • Kombinieren Sie DOM-Prüfungen mit API-Antworten für erweiterte Szenarien.

Ejemplo:

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

Hauptmerkmale

  • Überwachen Sie die Sichtbarkeit von Elementen, den Textinhalt oder benutzerdefinierte Eigenschaften.
  • Kombinieren Sie mehrere Bedingungen für komplexe Arbeitsabläufe.
  • Behandeln Sie Timeouts und Fehler ordnungsgemäß.

Tipp: Benutzen waitForFunction veraltete ersetzen sleep Anrufe und verbessern Sie die Effizienz.

Kurzübersicht:

Merkmal Was es macht
Polling-Modi Prüft Bedingungen über 'raf', 'mutation'oder benutzerdefinierte Intervalle
Benutzerdefinierte Bedingungen Warten auf bestimmte DOM-Zustände oder API-Antworten
Timeout-Verwaltung Festlegen vorgangsspezifischer oder globaler Timeouts

Diese Methode stellt sicher, dass Ihre Skripte zuverlässig und effizient sind und für jede Herausforderung dynamischer Inhalte bereit sind.

So warten/schlafen Sie N Sekunden in Puppenspieler?

Puppenspieler

Grundlagen von waitForFunction

Das waitForFunction Mit der Methode „Puppeteer“ können Sie benutzerdefinierte Bedingungen für Ihre Skripte festlegen, bevor diese fortgesetzt werden. So nutzen Sie sie effektiv.

So schreiben Sie grundlegende Wartefunktionen

So erstellen Sie auf einfache Weise eine 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'
);

Der Schlüssel hier ist, dass Ihre Funktion eine Wahrheitswert bevor das Skript fortgesetzt werden kann.

Sehen wir uns nun an, wie Sie es für eine bessere Leistung konfigurieren.

Einrichten von Funktionsparametern

Sie können die Feinabstimmung waitForFunction durch Übergabe eines Optionsobjekts. Wichtige Parameter sind:

Parameter Beschreibung Gemeinsame Werte
Polling Wie oft der Zustand überprüft wird 'raf', 'mutation' oder Millisekunden
Timeout Maximale Wartezeit Standard: 30,000 ms (30 Sekunden)

Polling-Modi:

  1. RequestAnimationFrame ('raf')
    Am besten geeignet für die Überwachung von Stiländerungen, da die Bedingungen während jedes Animationsbilds überprüft werden.
  2. Mutationsbeobachter ('Mutation')
    Nützlich zum Verfolgen von Änderungen in der DOM-Struktur. Es löst bei jeder DOM-Aktualisierung Prüfungen aus.
  3. Benutzerdefiniertes Intervall (Millisekunden)
    Beispielsweise wird die Bedingung jede Sekunde überprüft:
    await page.waitForFunction(
      () => document.readyState === 'complete',
      { polling: 1000, timeout: 5000 }
    );
    

Wählen Sie den Abfragemodus entsprechend Ihren Anforderungen:

  • Wasser 'raf' für Animationen oder Stilaktualisierungen.
  • Entscheide dich für 'mutation' für DOM-bezogene Änderungen.
  • Legen Sie für umfassendere Anwendungsfälle ein benutzerdefiniertes Intervall (Millisekunden) fest.

Erstellen benutzerdefinierter Warteregeln

Überprüfen des Elementanzeigestatus

Um zu bestätigen, dass ein Element sichtbar ist, können Sie seine Präsenz und Abmessungen überprü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 auf der Seite vorhanden ist und sichtbare Abmessungen aufweist. Dies ist besonders praktisch für dynamischer Inhalt das ordnungsgemäße Laden dauert eine Weile.

Testen von Text- und Elementeigenschaften

Über visuelle Kontrollen hinaus 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
);

Kombinieren mehrerer Warteregeln

Nachdem Sie einzelne Bedingungen getestet haben, können Sie diese für komplexere Szenarien 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 die Handhabung mehrerer Elemente mit unabhängigen Bedingungen verwenden Sie Promise Kombinationen:

Wartemuster Luftüberwachung Umsetzung
Alle Elemente Warten Sie auf mehrere erforderliche Elemente Promise.all()
Beliebiges Element Weiter, wenn das erste Element erscheint Promise.race()
Benutzerdefinierte Logik Behandeln Sie komplexe bedingte Prüfungen Kombinierte Wartefunktionen

Für asynchrone Vorgänge können Sie erweiterte 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 Validierung der API-Antwort mit DOM-Elementprüfungen, um sicherzustellen, dass sowohl die Daten als auch die visuellen Inhalte bereit sind.

sbb-itb-23997f1

Erweiterte waitForFunction-Methoden

Schreiben komplexer JavaScript-Bedingungen

Für dynamischere Webanwendungen können Sie warteAufFunktion 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:

  • Der Diagrammcontainer ist vorhanden.
  • Es ist eine Mindestanzahl an Datenpunkten vorhanden.
  • Alle Datenpunkte sind sichtbar.
  • Keiner der Punkte befindet sich im Ladezustand.

Für komplexere Szenarien können Sie auch asynchrone Prüfungen mit DOM-Auswertungen 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.

Umgang mit Zeitüberschreitungen und Fehlern

Das Timeout-Management ist entscheidend bei der Arbeit mit warteAufFunktionHier ist ein Beispiel für die effektive Handhabung von Timeouts:

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 kurzer Überblick über Timeout-Strategien:

Timeout-Strategie Luftüberwachung Konfiguration
Standard-Timeout Allgemeine Operationen page.setDefaultTimeout()
Navigations-Timeout Seitenladevorgänge page.setDefaultNavigationTimeout()
Betriebsspezifisch Detaillierte Kontrollen Verwenden Sie das timeout Option in Methode
Unendliches Warten Bekannte Verzögerungen timeout: 0

So verbessern Sie die Fehlerbehandlung:

  • Passen Sie die Timeout-Einstellungen basierend auf der Komplexität jedes Vorgangs an.
  • Wasser try-catch Blöcke, um Fehler ordnungsgemäß zu beheben.
  • Überwachen Sie die Netzwerkaktivität, um Engpässe zu identifizieren.
  • Implementieren Sie Fallback-Aktionen, wie etwa das Neuladen der Seite, wenn Timeouts auftreten.
  • Überprüfen Sie die Selektoren doppelt, um unnötige Verzögerungen zu vermeiden.

Diese Vorgehensweisen tragen dazu bei, dass Ihre Skripte sowohl zuverlässig als auch effizient sind.

waitForFunction schneller ausführen

Tipps zu Geschwindigkeit und Ressourcen

Um warteAufFunktion Um die Effizienz zu steigern, konzentrieren Sie sich auf intelligente Wartestrategien und ein angemessenes Ressourcenmanagement. Nutzen Sie Browser-Entwicklertools, 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 die Ressourcennutzung:

  • Blockieren Sie unnötige Elemente wie Bilder oder Schriftarten.
  • Wasser waitForSelector or waitForFunction statt veraltet waitForTimeout.
  • Kombinieren Sie mehrere Prüfungen in einer einzigen evaluate Aufruf, um die Kommunikation zwischen Browser und Knoten zu reduzieren.
Strategie Auswirkungen auf die Leistung Bester Anwendungsfall
networkidle2 Konservativ Seitennavigation
waitForSelector Schnell Einzelelementprüfungen
waitForFunction Variable Komplexe Bedingungen
Kombiniert evaluate Schnellste Mehrfachelementprüfungen

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

Häufige Probleme beheben

Leistungsprobleme entstehen oft durch ineffiziente Wartemuster. So gehen Sie damit um:

Selektorprobleme
Zu starre Selektoren können Fehler verursachen. 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 Schwachstellen beseitigt. Es besteht kein Bedarf für böse sleep[undefined] Aufrufe in Puppeteer-Skripten." - Puppeteers Readme

Verpacken Sie wartende Methoden immer in try...catch Blöcke, um Fehler ordnungsgemäß zu behandeln und Fallback-Optionen bereitzustellen. Dieser Ansatz stellt sicher, dass Ihre Skripte robust und zuverlässig bleiben.

Häufige Verwendungsmöglichkeiten für benutzerdefinierte Warteregeln

Laden von Produkten im Online-Shop

Um genaue Daten zu erfassen, ist es unerlässlich, dass Produkte korrekt geladen werden. Verwenden Sie eine benutzerdefinierte Warteregel, um die Ausführung anzuhalten, bis die Produkte 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});

Dadurch wird sichergestellt, dass Ihr Skript wartet, bis alle erforderlichen Elemente geladen sind, wodurch die Zuverlässigkeit der Datenerfassung in E-Commerce-Szenarien verbessert wird.

Laden von Inhalten in modernen Web-Apps

Dynamische Web-Apps erfordern oft bestimmte Wartebedingungen, um das Laden von Inhalten zu bewältigen. Sie können beispielsweise warten, bis ein bestimmtes Element vollständig sichtbar ist:

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

Wenn mehrere Abschnitte 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});

Mit dieser Methode stellen Sie sicher, dass Ihre Automatisierungsskripte nahtlos mit dynamischen Inhalten interagieren.

Erkennung von Formularfehlermeldungen

Die Erkennung von Formularfehlern erfolgt nach einer ähnlichen Logik wie die Überprüfung der Elementsichtbarkeit. 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 mithilfe bestimmter Wartebedingungen verfolgen:

Validierungstyp Wartebedingung Luftüberwachung
Feldfehler Überprüfen Sie, ob eine Fehlerklasse vorhanden ist Validierung einzelner Felder
Formularweite Fehler Überwachen des Fehlercontainers Gesamtformularstatus
Erfolgsmeldungen Achten Sie auf Bestätigungsanzeigen Abschluss der Übermittlung
Ladezustände Status der Schaltfläche „Senden“ verfolgen Verarbeitungshinweis

Schlussfolgerung

Key Take Away

Das waitForFunction Methode in Puppeteer wertet JavaScript-Bedingungen aus, bis sie zurückkehren true, und bietet präzise Kontrolle über dynamische Seiteninteraktionen.

Hier sind einige der wichtigsten Vorteile der Verwendung waitForFunction:

  • Flexible Auswertung: Verarbeitet asynchrone Funktionen zur Überwachung komplexer Seitenzustände.
  • Kontextintegration: Ermöglicht die direkte Übergabe von Node.js-Argumenten in den Browserkontext.
  • Benutzerdefinierte Logik: Ermöglicht maßgeschneiderte Automatisierung basierend auf bestimmten Seitenbedingungen.

Dieser Ansatz ist besonders praktisch, wenn Standard-Wartemethoden nicht ausreichen. Beispielsweise können in komplexen Single-Page-Anwendungen mehrere Elemente gleichzeitig geladen werden oder bestimmte JavaScript-Zustände müssen vor dem Fortfahren bestätigt werden.

Puppenspieler und Latenknoten in Aktion

Latenknoten

Latenode nutzt waitForFunction zur Verbesserung der Workflow-Automatisierung. Durch die Integration dieser Methode hat Latenode einen benutzerdefinierten Überwachungsknoten erstellt, der den Status von Websites überprüft und Screenshots erstellt, wenn bestimmte Bedingungen nicht erfüllt sind.

Hier ist ein Beispiel, wie Latenode verwendet waitForFunction um sicherzustellen, dass kritische Elemente vollständig gerendert sind, bevor Sie fortfahren:

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

Dieses Snippet wartet auf ein Element mit der Klasse .tv-lightweight-charts nicht nur im DOM angezeigt, sondern auch vollständig gerendert werden.

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

  • Legen Sie geeignete Timeout-Werte fest, indem Sie page.setDefaultTimeout().
  • Wasser try-catch Blöcke für eine robuste Fehlerbehandlung.
  • Verfolgen Sie die Ausführungszeiten, um Ihre Wartebedingungen zu optimieren.

Ähnliche Blog-Beiträge

Verwandte Blogs

Anwendungsfall

Unterstützt von