Ich benutze PhantomJS v1.4.1, um einige Webseiten zu laden. Ich habe keinen Zugriff auf ihre Serverseite, sondern erhalte nur Links, die auf sie verweisen. Ich verwende eine veraltete Version von Phantom, da ich Adobe Flash auf diesen Webseiten unterstützen muss.
Das Problem ist, dass viele Websites ihre geringfügigen Inhalte asynchron laden. Aus diesem Grund wurde der onLoadFinished-Rückruf von Phantom (analog für onLoad in HTML) zu früh ausgelöst, wenn noch nicht alles geladen ist. Kann jemand vorschlagen, wie ich warten kann, bis eine Webseite vollständig geladen ist, um beispielsweise einen Screenshot mit allen dynamischen Inhalten wie Anzeigen zu erstellen?
javascript
events
phantomjs
nilfalse
quelle
quelle
Antworten:
Ein anderer Ansatz besteht darin, PhantomJS zu bitten, nach dem Laden der Seite etwas zu warten, bevor das Rendern ausgeführt wird, wie im regulären Beispiel rasterize.js , jedoch mit einer längeren Zeitüberschreitung, damit das JavaScript das Laden zusätzlicher Ressourcen beenden kann:
quelle
Ich würde lieber regelmäßig nach dem
document.readyState
Status suchen ( https://developer.mozilla.org/en-US/docs/Web/API/document.readyState ). Obwohl dieser Ansatz etwas umständlich ist, können Sie sicher sein, dass Sie innerhalb deronPageReady
Funktion ein vollständig geladenes Dokument verwenden.Zusätzliche Erklärung:
Die Verwendung von verschachtelten
setTimeout
anstelle vonsetInterval
verhindert, dass sichcheckReadyState
"überlappen" und Rennbedingungen auftreten, wenn die Ausführung aus zufälligen Gründen verlängert wird.setTimeout
hat eine Standardverzögerung von 4 ms ( https://stackoverflow.com/a/3580085/1011156 ), sodass aktive Abfragen die Programmleistung nicht drastisch beeinträchtigen.document.readyState === "complete"
bedeutet, dass das Dokument vollständig mit allen Ressourcen geladen ist ( https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness ).quelle
readyState
wird erst ausgelöst, wenn das DOM vollständig geladen wurde.<iframe>
Möglicherweise werden jedoch noch Elemente geladen, sodass die ursprüngliche FrageSie können eine Kombination aus Waitfor- und Raster-Beispielen ausprobieren:
quelle
Möglicherweise können Sie die Rückrufe
onResourceRequested
und verwendenonResourceReceived
, um das asynchrone Laden zu erkennen. Hier ist ein Beispiel für die Verwendung dieser Rückrufe aus ihrer Dokumentation :Sie können sich auch
examples/netsniff.js
ein funktionierendes Beispiel ansehen .quelle
All the resource requests and responses can be sniffed using onResourceRequested and onResourceReceived
Hier ist eine Lösung, die darauf wartet, dass alle Ressourcenanforderungen abgeschlossen sind. Sobald der Vorgang abgeschlossen ist, wird der Seiteninhalt in der Konsole protokolliert und ein Screenshot der gerenderten Seite erstellt.
Obwohl diese Lösung als guter Ausgangspunkt dienen kann, habe ich festgestellt, dass sie fehlschlägt, sodass sie definitiv keine vollständige Lösung ist!
Ich hatte nicht viel Glück damit
document.readyState
.Ich wurde von dem Beispiel waitfor.js beeinflusst, das auf der Beispielseite von phantomjs zu finden ist .
quelle
In meinem Programm verwende ich eine Logik, um zu beurteilen, ob es onload war: Wenn ich die Netzwerkanforderung beobachte und in den letzten 200 ms keine neue Anforderung vorhanden war, behandle ich sie onload.
Verwenden Sie dies nach onLoadFinish ().
quelle
Ich fand diesen Ansatz in einigen Fällen nützlich:
Wenn Sie die Seite besitzen, geben Sie ein Skript ein:
quelle
Ich fand diese Lösung in einer NodeJS-App nützlich. Ich benutze es nur in verzweifelten Fällen, weil es eine Zeitüberschreitung auslöst, um auf das vollständige Laden der Seite zu warten.
Das zweite Argument ist die Rückruffunktion, die aufgerufen wird, sobald die Antwort fertig ist.
quelle
Dies ist eine Implementierung der Antwort von Supr. Außerdem wird setTimeout anstelle von setInterval verwendet, wie von Mateusz Charytoniuk vorgeschlagen.
Phantomjs werden in 1000 ms beendet, wenn keine Anfrage oder Antwort vorliegt.
quelle
Dies ist der Code, den ich benutze:
Grundsätzlich sollte man wissen, dass die Seite vollständig heruntergeladen ist, wenn ein bestimmtes Element im DOM angezeigt wird. Das Skript wird also warten, bis dies geschieht.
quelle
Ich verwende eine persönliche Mischung aus dem Phantomjs-
waitfor.js
Beispiel .Das ist meine
main.js
Datei:Und die
lib/waitFor.js
Datei (die nur ein Kopieren und Einfügen derwaifFor()
Funktion aus dem Phantomjs-waitfor.js
Beispiel ist ):Diese Methode ist nicht asynchron, aber ich bin mir zumindest sicher, dass alle Ressourcen geladen wurden, bevor ich versuche, sie zu verwenden.
quelle
Dies ist eine alte Frage, aber da ich nach dem vollständigen Laden von Seiten gesucht habe, aber nach Spookyjs (das casperjs und phantomjs verwendet) und meine Lösung nicht gefunden habe, habe ich dafür mein eigenes Skript erstellt, mit dem gleichen Ansatz wie der Benutzer deemstone. Dieser Ansatz bewirkt, dass die Seite für eine bestimmte Zeitspanne die Ausführung beendet, wenn sie keine Anforderung erhalten oder gestartet hat.
Fügen Sie in der Datei casper.js (wenn Sie sie global installiert haben, lautet der Pfad etwa /usr/local/lib/node_modules/casperjs/modules/casper.js) die folgenden Zeilen:
Am Anfang der Datei mit allen globalen Variablen:
Dann innerhalb der Funktion "createPage (casper)" direkt nach "var page = require ('webpage'). Create ();" Fügen Sie den folgenden Code hinzu:
Fügen Sie dann in "page.onResourceReceived = function onResourceReceived (resource) {" in der ersten Zeile Folgendes hinzu:
Machen Sie dasselbe für "page.onResourceRequested = function onResourceRequested (requestData, request) {"
Schließlich fügen Sie in der ersten Zeile unter "page.onLoadFinished = function onLoadFinished (status) {" Folgendes hinzu:
Und das war's, hoffe, dieser hilft jemandem in Schwierigkeiten wie ich. Diese Lösung ist für Casperjs, funktioniert aber direkt für Spooky.
Viel Glück !
quelle
Das ist meine Lösung, die für mich funktioniert hat.
quelle