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
truezurückgeben, sobald alles bereit ist. - Nutzen Sie Optionen wie die Polling-Frequenz (
raf,mutationoder 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:
| Funktion | Zweck |
|---|---|
| Polling-Modi | Prüft Bedingungen über „raf“, „mutation“ oder benutzerdefinierte Intervalle |
| Benutzerdefinierte Bedingungen | Wartet auf bestimmte DOM-Zustände oder API-Antworten |
| Timeout-Verwaltung | Legt 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:
| Parameter | Beschreibung | Gängige Werte |
|---|---|---|
| polling | Wie häufig die Bedingung geprüft wird | „raf“, „mutation“ oder Millisekunden |
| timeout | Maximale Wartezeit | Standard: 30.000 ms (30 Sekunden) |
Polling-Modi [4]:
RequestAnimationFrame („raf“)
Ideal zur Überwachung von Stiländerungen, da Bedingungen bei jedem Animationsframe geprüft werden.Mutation Observer („mutation“)
Nützlich zum Verfolgen von Änderungen in der DOM-Struktur. Prüfungen werden ausgelöst, sobald das DOM aktualisiert wird.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]:
| Wartemuster | Anwendungsfall | Implementierung |
|---|---|---|
| Alle Elemente | Auf mehrere erforderliche Elemente warten | Promise.all() |
| Beliebiges Element | Fortfahren, sobald das erste Element erscheint | Promise.race() |
| Benutzerdefinierte Logik | Komplexe bedingte Prüfungen verarbeiten | Kombinierte 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-Strategie | Anwendungsfall | Konfiguration |
|---|---|---|
| Standard-Timeout | Allgemeine Vorgänge | page.setDefaultTimeout() |
| Navigation-Timeout | Seitenladevorgänge | page.setDefaultNavigationTimeout() |
| Operationsspezifisch | Detaillierte Prüfungen | Die Option timeout in der Methode verwenden |
| Unbegrenztes Warten | Bekannte Verzögerungen | timeout: 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
waitForSelectoroderwaitForFunctionstatt des veraltetenwaitForTimeout. - Fassen Sie mehrere Prüfungen in einem einzigen
evaluate-Aufruf zusammen, um die Kommunikation zwischen Browser und Node zu reduzieren.
| Strategie | Performance-Auswirkung | Bester Anwendungsfall |
|---|---|---|
| networkidle2 | Moderat | Seitennavigation |
| waitForSelector | Schnell | Prüfungen einzelner Elemente |
| waitForFunction | Variabel | Komplexe Bedingungen |
| Kombiniertes evaluate | Am schnellsten | Prü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:
| Validierungstyp | Wartebedingung | Anwendungsfall |
|---|---|---|
| Feldfehler | Prüfen, ob eine Fehlerklasse vorhanden ist | Validierung einzelner Felder |
| Formularweite Fehler | Fehlercontainer überwachen | Gesamtstatus des Formulars |
| Erfolgsmeldungen | Auf Bestätigungsanzeigen achten | Abschluss der Übermittlung |
| Ladezustände | Status der Senden-Schaltfläche verfolgen | Anzeige 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.


