Ich möchte alle Daten einer Seite kratzen, die durch eine unendliche Schriftrolle implementiert wurde. Der folgende Python-Code funktioniert.
for i in range(100):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
Dies bedeutet, dass ich jedes Mal, wenn ich nach unten scrolle, 5 Sekunden warten muss, was im Allgemeinen ausreicht, damit die Seite den neu generierten Inhalt vollständig lädt. Dies ist jedoch möglicherweise nicht zeiteffizient. Die Seite lädt den neuen Inhalt möglicherweise innerhalb von 5 Sekunden. Wie kann ich feststellen, ob die Seite den neuen Inhalt bei jedem Bildlauf nach unten geladen hat? Wenn ich dies feststellen kann, kann ich erneut nach unten scrollen, um weitere Inhalte anzuzeigen, sobald ich weiß, dass die Seite vollständig geladen wurde. Dies ist zeiteffizienter.
python
selenium
execute-script
Apogne
quelle
quelle
Antworten:
Das
webdriver
wartet darauf, dass eine Seite standardmäßig über die.get()
Methode geladen wird .Da Sie möglicherweise nach einem bestimmten Element suchen, wie @ user227215 sagte, sollten Sie verwenden
WebDriverWait
, um auf ein Element auf Ihrer Seite zu warten:Ich habe es zum Überprüfen von Warnungen verwendet. Sie können beliebige andere Typmethoden verwenden, um den Locator zu finden.
EDIT 1:
Ich sollte erwähnen, dass das
webdriver
standardmäßig auf das Laden einer Seite wartet. Es wartet nicht auf das Laden innerhalb von Frames oder auf Ajax-Anfragen. Wenn Sie verwenden.get('url')
, wartet Ihr Browser, bis die Seite vollständig geladen ist, und fährt dann mit dem nächsten Befehl im Code fort. Wenn Sie jedoch eine Ajax-Anfrage stellen,webdriver
warten Sie nicht und es liegt in Ihrer Verantwortung, eine angemessene Zeit zu warten, bis die Seite oder ein Teil der Seite geladen ist. Es gibt also ein Modul mit dem Namenexpected_conditions
.quelle
browser.find_element_by_id('IdOfMyElement')
das Passieren wird einNoSuchElementException
erhöht. In der Dokumentation heißt es, ein Tupel zu übergeben, das so aussieht :(By.ID, 'IdOfMyElement')
. Siehe meine Antwortclick()
), Text auslesen usw. Ich hatte den falschen Eindruck, dass es einfach ist verursachte eine Wartezeit, nach der man das Element noch finden musste. Wenn Sie warten und anschließend ein Element suchen, tritt ein Fehler bei Selen auf, da versucht wird, das Element zu finden, während das alte Warten noch verarbeitet wird (hoffentlich ist dies sinnvoll). Unter dem Strich müssen Sie das Element nach der Verwendung von WebDriverWait nicht finden - es ist bereits ein Objekt.Der Versuch,
find_element_by_id
an den Konstruktor zu übergebenpresence_of_element_located
(wie in der akzeptierten Antwort gezeigt ), wurde ausgelöstNoSuchElementException
. Ich musste die Syntax in Fragles ' Kommentar verwenden :Dies entspricht dem Beispiel in der Dokumentation . Hier ist ein Link zur Dokumentation für By .
quelle
EC.presence_of_element_located((By.XPATH, "//*[@title='Check All Q1']"))
By
Objekt verfügbar sind .Finden Sie unten 3 Methoden:
readyState
Überprüfung der Seite readyState (nicht zuverlässig):
id
Vergleich neuer Seiten-IDs mit den alten:
staleness_of
Mit
staleness_of
Methode:Weitere Informationen finden Sie in Harrys Blog .
quelle
self.driver.execute_script('return document.readyState;')
nicht zuverlässig? Es scheint perfekt für meinen Anwendungsfall zu funktionieren, der darauf wartet, dass eine statische Datei in einen neuen Tab geladen wird (der über Javascript in einem anderen Tab anstelle von .get () geöffnet wird).Wie in der Antwort von David Cullen erwähnt , habe ich immer Empfehlungen gesehen, eine Zeile wie die folgende zu verwenden:
Es war schwierig für mich, irgendwo alle möglichen Locators zu finden, die mit dem verwendet werden können
By
, daher dachte ich, es wäre nützlich, die Liste hier bereitzustellen. Laut Web Scraping with Python von Ryan Mitchell:quelle
Von selenium / webdriver / support / wait.py
quelle
Nebenbei bemerkt, anstatt 100 Mal nach unten zu scrollen, können Sie überprüfen, ob keine Änderungen mehr am DOM vorgenommen wurden (wir sind im Fall, dass das Ende der Seite AJAX faul geladen wird).
quelle
Hast du es versucht
driver.implicitly_wait
? Es ist wie eine Einstellung für den Treiber, Sie rufen sie also nur einmal in der Sitzung auf und der Treiber wird grundsätzlich angewiesen, die angegebene Zeit zu warten, bis jeder Befehl ausgeführt werden kann.Wenn Sie also eine Wartezeit von 10 Sekunden festlegen, wird der Befehl so schnell wie möglich ausgeführt und 10 Sekunden gewartet, bevor er aufgibt. Ich habe dies in ähnlichen Scroll-Down-Szenarien verwendet, daher verstehe ich nicht, warum es in Ihrem Fall nicht funktionieren würde. Hoffe das ist hilfreich.
Um diese Antwort korrigieren zu können, muss ich neuen Text hinzufügen. Stellen Sie sicher, dass Sie ein Kleinbuchstaben "w" verwenden
implicitly_wait
.quelle
Wie wäre es, wenn Sie WebDriverWait in die While-Schleife einfügen und die Ausnahmen abfangen.
quelle
Hier habe ich es mit einer ziemlich einfachen Form gemacht:
quelle
Mit dieser Funktion können Sie das ganz einfach tun:
und wenn Sie nach dem vollständigen Laden der Seite etwas tun möchten, können Sie Folgendes verwenden:
quelle