Ich sende ein Formular mit dem folgenden Code und möchte, dass Puppeteer das Laden der Seite nach dem Senden des Formulars wartet.
await page.click("button[type=submit]");
//how to wait until the new page loads before taking screenshot?
// i don't want this:
// await page.waitFor(1*1000); //← unwanted workaround
await page.screenshot({path: 'example.png'});
Wie kann ich mit dem Puppenspieler auf das Laden der Seite warten?
javascript
puppeteer
Redochka
quelle
quelle
networkidle
sollte jetzt aufnetworkidle2
github.com/GoogleChrome/puppeteer/blob/master/docs/… eingestellt werdenawait page.waitForNavigation();
quelle
await Promise.all([page.click..., page.waitForNavigation...]);
?Gemäß der offiziellen Dokumentation sollten Sie Folgendes verwenden:
Lesbarkeit:
Sie können
page.waitForNavigation()
warten, bis eine Seite navigiert ist:await page.waitForNavigation();
Performance:
Da dies
page.waitForNavigation()
jedoch eine Abkürzung für istpage.mainFrame().waitForNavigation()
, können wir Folgendes für eine geringfügige Leistungssteigerung verwenden:await page._frameManager._mainFrame.waitForNavigation();
quelle
Ich weiß, dass es etwas spät ist, dies zu beantworten. Dies kann hilfreich sein für diejenigen, die während der Ausführung von waitForNavigation unter die Ausnahme geraten .
Der richtige Code, der für mich funktioniert hat, ist wie folgt.
await page.click('button[id=start]', {waitUntil: 'domcontentloaded'});
Wenn Sie zu einer neuen Seite gehen, sollte der Code ähnlich sein
await page.goto('here goes url', {waitUntil: 'domcontentloaded'});
quelle
Manchmal führt sogar die Verwendung zu
await page.waitForNavigation()
einemError: Execution context was destroyed, most likely because of a navigation.
In meinem Fall lag es daran, dass die Seite mehrmals umgeleitet wurde. Die API gibt an, dass die Standardoption
waitUntil
lautetLoad
Ich muss bei jeder Umleitung (dreimal) auf die Navigation warten.In meinem Fall hat es gut funktioniert, nur eine einzige Instanz von
page.waitForNavigation
mit derwaitUntil
Option zu verwendennetworkidle2
:await button.click(); await page.waitForNavigation({waitUntil: 'networkidle2'});
Schließlich schlägt die API vor, a
Promise.All
zu verwenden, um eine Rennbedingung zu verhindern. Ich habe das nicht gebraucht, aber der Vollständigkeit halber angegeben :await Promise.all([button.click(), page.waitForNavigation({waitUntil:'networkidle2'})])
Wenn alles andere fehlschlägt, können Sie es
page.waitForSelector
wie empfohlen für ein Puppenspieler-Github-Problem verwenden - oder in meinem Fall:page.waitForXPath()
quelle
networkidle0
richtig funktionierte.Ich schlage vor, page.to in einen Wrapper zu verpacken und auf alles zu warten, was geladen wurde
Das ist mein Wrapper
loadUrl: async function (page, url) { try { await page.goto(url, { timeout: 20000, waitUntil: ['load', 'domcontentloaded', 'networkidle0', 'networkidle2'] }) } catch (error) { throw new Error("url " + url + " url not loaded -> " + error) } }
Jetzt können Sie dies mit verwenden
await loadUrl(page, "https://www.google.com")
quelle
networkidle0
durch das Warten ersetztnetworkidle2
?await Promise.all([ page.click(selectors.submit), page.waitForNavigation({ waitUntil: 'networkidle0' }), ]);
Dies ist die erste Priorität, die verwendet werden muss, da darauf gewartet wird, dass das gesamte Netzwerk abgeschlossen ist, und davon ausgegangen wird, dass dies erfolgt, wenn Sie 500 ms lang nicht mehr als 0 Netzwerkanrufe haben.
Sie können auch verwenden
await page.waitForNavigation({ waitUntil: 'Load' })
oder Sie können verwenden
await page.waitForResponse(response => response.ok())
Diese Funktion kann auch an verschiedenen Stellen verwendet werden, da sie nur dann fortgesetzt werden kann, wenn alle Anrufe erfolgreich sind, dh wenn der gesamte Antwortstatus in Ordnung ist, dh (200-299).
quelle
waitUntil: 'load'
. Nur Kleinbuchstaben sind gültig. ref: github.com/puppeteer/puppeteer/blob/master/docs/…Ich bin auf ein Szenario gestoßen, in dem es den klassischen POST-303-GET gab und an dem ein
input[type=submit]
beteiligt war. Es scheint, dass in diesem Fallclick
die Schaltfläche erst nach dem Senden und Umleiten des zugehörigen Formulars aufgelöst wird. Daher bestand die Lösung darin, das zu entfernenwaitForNavigation
, da es nach der Umleitung ausgeführt wurde und somit eine Zeitüberschreitung aufwies.quelle
Das hat bei mir funktioniert:
await Promise.all([ page.goto(URL), page.waitForNavigation({ waitUntil: 'networkidle0' }), ]); console.log('page loaded')
Aus irgendeinem Grund konnte ich nicht auf die Schaltfläche klicken (Ereignis behandelt, nicht in Form)
<button onclick="someFunction();" class="button button2">Submit</button>
Das Problem war, dass die Seite auf der Serverseite gerendert wurde. Daher existierte die Schaltfläche nicht, wenn ich auf ein Eingabefeld wartete
await page.waitForSelector('button.button2')
Die Lösung war zu binden
page.goto(URL)
undpage.waitForNavigation({ waitUntil: 'networkidle0' })
inPromise
await Promise.all([ page.goto(URL), page.waitForNavigation({ waitUntil: 'networkidle0' }), ]); console.log('page loaded') await page.waitForSelector('button.button2') console.log('button is here');
quelle