Puppenspieler-Warteseite wird nach dem Absenden des Formulars geladen

Lesezeit: 5 Minuten

Benutzer-Avatar
Redochka

Ich sende ein Formular mit dem folgenden Code und möchte, dass Puppeteer nach dem Absenden des Formulars auf das Laden der Seite 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 Puppeteer auf das Laden der Seite warten?

Benutzer-Avatar
Md. Abu Taher

Sie können asynchron auf die Navigation warten, um ein Einholen zu vermeiden null bei Weiterleitung,

await Promise.all([
    page.click('button[type=submit]'),
    page.waitForNavigation({waitUntil: 'networkidle2'})
]);

Dies hilft Ihnen, wenn der page.click bereits eine Navigation auslöst.

await page.waitForNavigation();

  • Was ist der Unterschied zwischen diesem und await Promise.all([page.click..., page.waitForNavigation...]); ?

    – Nathan Goings

    16. Oktober 2019 um 3:13 Uhr

  • @NathanGoings Hier ist nur ein Versprechen zu lösen, während das Versprechen mehrere Versprechen löst (nicht unbedingt nacheinander).

    – Mabu

    29. April 2021 um 13:39 Uhr


Laut dem Offizielle Dokumentationdu solltest benutzen:

page.waitForNavigation (Optionen)

  • options <Objekt> Navigationsparameter, die folgende Eigenschaften haben können:
    • timeout <Nummer> Maximale Navigationszeit in Millisekunden, standardmäßig 30 Sekunden, pass 0 um die Zeitüberschreitung zu deaktivieren. Der Standardwert kann mit geändert werden page.setDefaultNavigationTimeout (Zeitüberschreitung) Methode.
    • waitUntil <Schnur|Array<Schnur>> Wenn die Navigation als erfolgreich betrachtet wird, ist die Standardeinstellung auf load. Bei einem Array von Ereigniszeichenfolgen gilt die Navigation als erfolgreich, nachdem alle Ereignisse ausgelöst wurden. Ereignisse können entweder sein:
      • load – Navigation als beendet betrachten, wenn die load Ereignis wird ausgelöst.
      • domcontentloaded – Navigation als beendet betrachten, wenn die DOMContentLoaded Ereignis wird ausgelöst.
      • networkidle0 – Navigation als beendet betrachten, wenn mindestens 0 Netzwerkverbindungen vorhanden sind 500 MS.
      • networkidle2 – Navigation als beendet betrachten, wenn mindestens 2 Netzwerkverbindungen bestehen 500 MS.
  • gibt zurück: <Versprechen<[?Response]>> Versprechen, das zur Antwort der Hauptressource führt. Bei mehreren Weiterleitungen wird die Navigation mit der Antwort der letzten Weiterleitung aufgelöst. Im Falle einer Navigation zu einem anderen Anker oder einer Navigation aufgrund der Verwendung der Verlaufs-API wird die Navigation mit aufgelöst null.

Lesbarkeit:

Sie können verwenden page.waitForNavigation() warten, bis eine Seite navigiert:

await page.waitForNavigation();

Leistung:

Aber seit page.waitForNavigation() ist eine Abkürzung für page.mainFrame().waitForNavigation()können wir Folgendes für eine geringfügige Leistungssteigerung verwenden:

await page._frameManager._mainFrame.waitForNavigation();

  • Ich versuche zu warten, bis ein Bild in einem Popover geladen wird. Ist es möglich, einfach 10 Sekunden zu pausieren? Keiner dieser Werte funktioniert für mich.

    – Chovy

    13. August 2019 um 6:30 Uhr

  • Der Leistungshinweis ist eine verfrühte Optimierung und hat keinen praktischen Einfluss auf die Leistung in der realen Welt. Außerdem ist es wahrscheinlicher, dass es nach einem Upgrade von Puppeteer kaputt geht, da es die interne API verwendet

    – Soufiane Ghzal

    10. Januar 2020 um 11:57 Uhr

Benutzer-Avatar
Nathan Gehen

Manchmal sogar mit await page.waitForNavigation() führt immer noch zu a Error: Execution context was destroyed, most likely because of a navigation.

In meinem Fall lag es daran, dass die Seite mehrmals umgeleitet wurde. Das API sagt die Vorgabe waitUntil Option ist Load– Dies erforderte, dass ich bei jeder Umleitung (3 Mal) auf die Navigation wartete.

Verwenden Sie nur eine einzige Instanz von page.waitForNavigation mit dem waitUntil Möglichkeit networkidle2 hat bei mir gut funktioniert:

await button.click();

await page.waitForNavigation({waitUntil: 'networkidle2'});

Schließlich schlägt die API die Verwendung von a vor Promise.All um eine Race-Condition zu verhindern. Ich habe das nicht benötigt, stelle es aber der Vollständigkeit halber zur Verfügung:

await Promise.all([button.click(), page.waitForNavigation({waitUntil:'networkidle2'})])

Wenn alles andere fehlschlägt, können Sie verwenden page.waitForSelector wie auf a empfohlen Puppeteer-Github-Problem– oder in meinem Fall page.waitForXPath()

Ich weiß, es ist etwas spät, darauf zu antworten. Es kann hilfreich sein für diejenigen, die dabei unter die Ausnahme kommen WaitForNavigation.

(node:14531) UnhandledPromiseRejectionWarning: TimeoutError: Navigation Timeout Exceeded: 30000ms überschritten bei Promise.then (/home/user/nodejs/node_modules/puppeteer/lib/LifecycleWatcher.js:142:21) bei — ASYNC — bei Frame. (/home/user/nodejs/node_modules/puppeteer/lib/helper.js:111:15) unter Page.waitForNavigation (/home/user/nodejs/node_modules/puppeteer/lib/Page.js:649:49) unter Page . (/home/user/nodejs/node_modules/puppeteer/lib/helper.js:112:23) unter /home/user/nodejs/user/puppeteer/example7.js:14:12 at

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 wechseln, sollte der Code ähnlich sein

await page.goto('here goes url', {waitUntil: 'domcontentloaded'});

Benutzer-Avatar
Andrea Bisello

Ich schlage vor, page.to in einen Wrapper zu packen und zu warten, bis alles geladen ist

das ist meine Verpackung

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

await Promise.all([
      page.click(selectors.submit),
      page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);

Dies wäre die erste zu verwendende Priorität, da darauf gewartet wird, dass das gesamte Netzwerk abgeschlossen ist, und davon ausgegangen wird, dass dies abgeschlossen ist, wenn Sie 500 ms lang nicht mehr als 0 Netzwerkanrufe haben.

kannst du auch verwenden

await page.waitForNavigation({ waitUntil: 'load' })

oder sonst können Sie verwenden

await page.waitForResponse(response => response.ok())

Diese Funktion kann auch an verschiedenen Stellen verwendet werden, da sie nur dann weitergehen kann, wenn alle Anrufe erfolgreich waren, d. h. wenn der gesamte Antwortstatus in Ordnung ist, dh (200-299).

1212680cookie-checkPuppenspieler-Warteseite wird nach dem Absenden des Formulars geladen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy