Wie kann ich mit Selenium Webdriver in Python eine Webseite scrollen?


129

Ich verwende derzeit Selenium Webdriver, um die Facebook-Seite mit Freunden von Freunden zu analysieren und alle IDs aus dem AJAX-Skript zu extrahieren. Aber ich muss nach unten scrollen, um alle Freunde zu bekommen. Wie kann ich in Selen nach unten scrollen? Ich benutze Python.


2
Mögliches Duplikat von Wie man eine Seite mit Selen
Louis

driver.execute_script (f "window.scrollTo (0, {2 ** 127});")
AturSams

Antworten:


261

Sie können verwenden

driver.execute_script("window.scrollTo(0, Y)") 

Dabei ist Y die Höhe (auf einem Full-HD-Monitor sind es 1080). (Danke an @lukeis)

Sie können auch verwenden

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

um zum Ende der Seite zu scrollen .

Wenn Sie zu einer Seite mit unendlichem Laden scrollen möchten , z. B. zu sozialen Netzwerken, Facebook usw. (danke an @Cuong Tran)

SCROLL_PAUSE_TIME = 0.5

# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

Eine andere Methode (dank Juanse) ist, ein Objekt auszuwählen und

label.sendKeys(Keys.PAGE_DOWN);

1
Ausgezeichnet, können Sie ein wenig erklären scrollHeight, was es bedeutet und wie es im Allgemeinen funktioniert?
Jason Goal

Wie würden Sie dann die Variable "last_height" verwenden? Ich habe etwas Ähnliches in meinem Code und der Browser scrollt nach unten. Wenn ich mir jedoch die Daten ansehe, die ich kratzt, kratzt es nur die Daten von der ersten Seite k-mal, wobei "k" die Häufigkeit ist, mit der der Browser nach unten scrollt.
Peter Lenaers

72

Wenn Sie zum Ende der unendlichen Seite scrollen möchten (wie linkedin.com ), können Sie diesen Code verwenden:

SCROLL_PAUSE_TIME = 0.5

# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

Referenz: https://stackoverflow.com/a/28928684/1316860


Das ist toll. Für alle, die versuchen, dies auf Instagram zu verwenden, müssen Sie möglicherweise zuerst mit ActionChains auf die Schaltfläche "Mehr laden" klicken und dann die Lösung von Cuong Tran anwenden ... zumindest hat das bei mir funktioniert.
Mwspencer

Danke für die Antwort! Was ich tun möchte, ist zum Beispiel in Instagram zum Ende der Seite zu scrollen und dann das gesamte HTML der Seite abzurufen. Gibt es eine Funktion in Selen, bei der ich last_height als Eingabe angeben und die gesamte HTML-Seite abrufen kann, nachdem ich nach unten gescrollt habe?
Swan87

2
Das SCROLL_PAUSE_TIMEvariiert, es dauert ungefähr 2 Sekunden für mich.
SSI-Anik


21

gleiche Methode wie hier gezeigt :

In Python können Sie einfach verwenden

driver.execute_script("window.scrollTo(0, Y)")

(Y ist die vertikale Position, zu der Sie scrollen möchten)


15
element=find_element_by_xpath("xpath of the li you are trying to access")

element.location_once_scrolled_into_view

Dies half, als ich versuchte, auf ein 'li' zuzugreifen, das nicht sichtbar war.


'find_element_by_xpath' ist eine Treiberfunktion oder was, die '.location_once_scrolled_into_view' gibt den Fehler NoSuchElementException zurück: Nachricht: kein solches Element: Element kann nicht gefunden werden: {"method": "xpath", "selector": "// * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Walid Bousseta

Nur noch eine Sache. Der Grund, warum location_once_scrolled_into_viewohne aufgerufen werden sollte, () ist, dass location_once_scrolled_into_viewes sich um einen Python handelt property. Den Quellcode finden Sie hier: selenium / webelement.py unter d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ /
selenium

10

Zu meinem Zweck wollte ich mehr nach unten scrollen und dabei die Position der Fenster berücksichtigen. Meine Lösung war ähnlich und verwendetwindow.scrollY

driver.execute_script("window.scrollTo(0, window.scrollY + 200)")

Dies wird zur aktuellen y-Bildlaufposition + 200 gehen


8

So scrollen Sie auf der Webseite nach unten:

driver.execute_script("window.scrollTo(0, 1000);")

7

Der einfachste Weg, dieses Problem zu lösen, bestand darin, ein Etikett auszuwählen und dann zu senden:

label.sendKeys(Keys.PAGE_DOWN);

Hoffe, es funktioniert!


6

Keine dieser Antworten hat bei mir funktioniert, zumindest nicht beim Scrollen einer Facebook-Suchergebnisseite, aber ich habe nach vielen Tests dieser Lösung Folgendes gefunden:

while driver.find_element_by_tag_name('div'):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    Divs=driver.find_element_by_tag_name('div').text
    if 'End of Results' in Divs:
        print 'end'
        break
    else:
        continue

Es funktioniert, aber sehr langsam (zumindest für mich). Ich habe festgestellt, dass wenn Sie SCROLL_PAUSE_TIMEin stackoverflow.com/a/27760083/7326714 auf setzen 2, es gut funktioniert und Sie 100x schneller nach unten scrollen.
LucSpan

6

Wenn Sie mit YouTube arbeiten, geben die schwebenden Elemente den Wert "0" als Bildlaufhöhe an. Verwenden Sie also "return document.body.scrollHeight" , anstatt "return document.documentElement.scrollHeight" zu verwenden. Passen Sie die Bildlaufpausenzeit gemäß Ihrem Internet an Geschwindigkeit sonst läuft es nur einmal und bricht danach ab.

SCROLL_PAUSE_TIME = 1

# Get scroll height
"""last_height = driver.execute_script("return document.body.scrollHeight")

this dowsnt work due to floating web elements on youtube
"""

last_height = driver.execute_script("return document.documentElement.scrollHeight")
while True:
    # Scroll down to bottom
    driver.execute_script("window.scrollTo(0,document.documentElement.scrollHeight);")

    # Wait to load page
    time.sleep(SCROLL_PAUSE_TIME)

    # Calculate new scroll height and compare with last scroll height
    new_height = driver.execute_script("return document.documentElement.scrollHeight")
    if new_height == last_height:
       print("break")
       break
    last_height = new_height

5

Ich suchte nach einer Möglichkeit, durch eine dynamische Webseite zu scrollen und automatisch anzuhalten, sobald das Ende der Seite erreicht ist, und fand diesen Thread.

Der Beitrag von @Cuong Tran mit einer Hauptänderung war die Antwort, nach der ich gesucht habe. Ich dachte, dass andere die Änderung hilfreich finden könnten (sie hat einen ausgeprägten Einfluss auf die Funktionsweise des Codes), daher dieser Beitrag.

Die Änderung besteht darin, die Anweisung zu verschieben, die die letzte Seitenhöhe innerhalb der Schleife erfasst (sodass jede Prüfung mit der vorherigen Seitenhöhe verglichen wird).

Also, der Code unten:

Scrollt kontinuierlich eine dynamische Webseite ( .scrollTo()) nach unten und stoppt nur, wenn für eine Iteration die Seitenhöhe gleich bleibt.

(Es gibt eine weitere Änderung, bei der sich die break-Anweisung in einer anderen Bedingung befindet (falls die Seite "klebt"), die entfernt werden kann.)

    SCROLL_PAUSE_TIME = 0.5


    while True:

        # Get scroll height
        ### This is the difference. Moving this *inside* the loop
        ### means that it checks if scrollTo is still scrolling 
        last_height = driver.execute_script("return document.body.scrollHeight")

        # Scroll down to bottom
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

        # Wait to load page
        time.sleep(SCROLL_PAUSE_TIME)

        # Calculate new scroll height and compare with last scroll height
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:

            # try again (can be removed)
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

            # Wait to load page
            time.sleep(SCROLL_PAUSE_TIME)

            # Calculate new scroll height and compare with last scroll height
            new_height = driver.execute_script("return document.body.scrollHeight")

            # check if the page height has remained the same
            if new_height == last_height:
                # if so, you are done
                break
            # if not, move on to the next loop
            else:
                last_height = new_height
                continue

5

Dieser Code scrollt nach unten, erfordert jedoch nicht, dass Sie jedes Mal warten. Es wird kontinuierlich gescrollt und dann unten angehalten (oder Timeout)

from selenium import webdriver
import time

driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('https://example.com')

pre_scroll_height = driver.execute_script('return document.body.scrollHeight;')
run_time, max_run_time = 0, 1
while True:
    iteration_start = time.time()
    # Scroll webpage, the 100 allows for a more 'aggressive' scroll
    driver.execute_script('window.scrollTo(0, 100*document.body.scrollHeight);')

    post_scroll_height = driver.execute_script('return document.body.scrollHeight;')

    scrolled = post_scroll_height != pre_scroll_height
    timed_out = run_time >= max_run_time

    if scrolled:
        run_time = 0
        pre_scroll_height = post_scroll_height
    elif not scrolled and not timed_out:
        run_time += time.time() - iteration_start
    elif not scrolled and timed_out:
        break

# closing the driver is optional 
driver.close()

Dies ist viel schneller als jedes Mal 0,5 bis 3 Sekunden auf eine Antwort zu warten, wenn diese Antwort 0,1 Sekunden dauern kann


3

Bildlaufseiten scrollen. Beispiel: Medium, Quora usw.

last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight-1000);")
        # Wait to load the page.
        driver.implicitly_wait(30) # seconds
        new_height = driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:
            break
        last_height = new_height
        # sleep for 30s
        driver.implicitly_wait(30) # seconds
        driver.quit()

sollte driver.quit () außerhalb des while-Blocks liegen oder nicht? und auch das letzte implizite Warten ist nicht erforderlich .. jemand pls bestätigen. @ashishmishra
ihightower

1

Wenn Sie innerhalb einer bestimmten Ansicht / eines bestimmten Rahmens (WebElement) scrollen möchten, müssen Sie nur "body" durch ein bestimmtes Element ersetzen, in dem Sie scrollen möchten . Ich erhalte dieses Element über "getElementById" im folgenden Beispiel:

self.driver.execute_script('window.scrollTo(0, document.getElementById("page-manager").scrollHeight);')

Dies ist zum Beispiel bei YouTube der Fall ...


1

Die ScrollTo()Funktion funktioniert nicht mehr. Das habe ich benutzt und es hat gut funktioniert.

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")

Nur diese Methode hat in meinem Fall funktioniert, andere nicht. Vielen Dank.
ePandit

0
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

es funktioniert für meinen Fall.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.