Come posso scorrere una pagina web usando selenium webdriver in Python?


132

Attualmente sto usando selenium webdriver per analizzare la pagina degli amici degli utenti di Facebook ed estrarre tutti gli ID dallo script AJAX. Ma devo scorrere verso il basso per ottenere tutti gli amici. Come posso scorrere verso il basso in Selenio. Sto usando Python.


2
possibile duplicato di Come scorrere la pagina con selenio
Louis

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

Risposte:


264

Puoi usare

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

dove Y è l'altezza (su un monitor FullHD è 1080). (Grazie a @lukeis)

Puoi anche usare

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

per scorrere fino alla fine della pagina.

Se vuoi scorrere fino a una pagina con caricamento infinito , come quelli dei social network, Facebook ecc. (Grazie a @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

un altro metodo (grazie a Juanse) è, selezionare un oggetto e

label.sendKeys(Keys.PAGE_DOWN);

1
Eccellente, puoi spiegarci un po ' scrollHeight, cosa significa e come funziona in generale?
Jason Goal,

Come useresti quindi la variabile "last_height"? Ho qualcosa di simile nel mio codice e il browser scorre verso il basso. Tuttavia, quando guardo i dati che sto raschiando, raschia solo i dati dalla prima pagina k volte con "k" che è il numero di volte che il browser scorre verso il basso.
Peter Lenaers,

72

Se vuoi scorrere fino alla fine della pagina infinita (come linkedin.com ), puoi usare questo codice:

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

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


Questo è fantastico Per chiunque stia cercando di usare questo su Instagram, potrebbe essere necessario prima fare clic sul pulsante "Carica altro" usando ActionChains, quindi applicare la soluzione di Cuong Tran ... almeno è quello che ha funzionato per me.
Mwspencer,

Grazie per la risposta! Quello che vorrei fare è scorrere ad esempio in Instagram fino alla fine della pagina, quindi prendere l'intero HTML della pagina. Esiste una funzione in selenio in cui potrei dare last_height come input e ottenere l'intera pagina html, dopo che sono passato in fondo?
Swan87,

2
Il SCROLL_PAUSE_TIMEvaria, ci vogliono circa 2 secondi.
ssi-anik,


21

stesso metodo mostrato qui :

in Python puoi semplicemente usare

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

(Y è la posizione verticale che si desidera scorrere)


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

element.location_once_scrolled_into_view

questo mi ha aiutato quando stavo tentando di accedere a una "li" che non era visibile.


'find_element_by_xpath' è una funzione del driver o cosa, il '.location_once_scrolled_into_view' restituisce l'errore NoSuchElementException: Messaggio: nessun elemento del genere: Impossibile individuare l'elemento: {"method": "xpath", "selector": "// * * [@ id = "timeline-medley"] / div / div [2] / div [1] "}
Walid Bousseta,

Solamente un'altra cosa. Il motivo per cui location_once_scrolled_into_viewdovrebbe essere chiamato senza () è che location_once_scrolled_into_viewè un Python property. vedi il codice sorgente qui: selenium / webelement.py su d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ /
selenium

10

Per il mio scopo, volevo scorrere di più verso il basso, tenendo presente la posizione delle finestre. La mia soluzione era simile e usatawindow.scrollY

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

che andrà all'attuale posizione di scorrimento y + 200


8

Ecco come scorrere la pagina Web:

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

7

Il modo più semplice che ho trovato per risolvere il problema era selezionare un'etichetta e quindi inviare:

label.sendKeys(Keys.PAGE_DOWN);

Spero funzioni!


6

Nessuna di queste risposte ha funzionato per me, almeno non per scorrere una pagina dei risultati di ricerca di Facebook, ma ho trovato dopo molti test questa soluzione:

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

Funziona, ma molto lentamente (almeno per me). Ho scoperto che se si imposta SCROLL_PAUSE_TIMEin stackoverflow.com/a/27760083/7326714 a 2, funziona bene e si scorre un 100 volte più veloce.
LucSpan,

6

Quando si lavora con YouTube, gli elementi mobili danno il valore "0" come altezza di scorrimento, quindi piuttosto che usare "return document.body.scrollHeight" provare a usare questo "return document.documentElement.scrollHeight" regolare il tempo di pausa di scorrimento come da Internet velocità altrimenti funzionerà per una sola volta e poi si romperà dopo.

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

Stavo cercando un modo per scorrere una pagina Web dinamica e fermarmi automaticamente una volta raggiunta la fine della pagina, e ho trovato questa discussione.

Il post di @Cuong Tran , con una modifica principale, è stata la risposta che stavo cercando. Ho pensato che altri potrebbero trovare utile la modifica (ha un effetto pronunciato su come funziona il codice), quindi questo post.

La modifica consiste nello spostare l'istruzione che acquisisce l'altezza dell'ultima pagina all'interno del ciclo (in modo che ciascun controllo sia confrontato con l'altezza della pagina precedente).

Quindi, il codice qui sotto:

Scorre continuamente verso il basso una pagina Web dinamica ( .scrollTo()), fermandosi solo quando, per una iterazione, l'altezza della pagina rimane invariata.

(Esiste un'altra modifica, in cui l'istruzione break si trova all'interno di un'altra condizione (nel caso la pagina 'si attacca') che può essere rimossa).

    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

Questo codice scorre verso il basso ma non richiede di aspettare ogni volta. Scorrerà continuamente, quindi si fermerà in fondo (o 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()

Questo è molto più veloce che aspettare 0,5-3 secondi ogni volta per una risposta, quando quella risposta potrebbe richiedere 0,1 secondi


3

scorrere le pagine di caricamento. Esempio: medium, quora, ecc

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

1
driver.quit () dovrebbe essere al di fuori del blocco while o no? e anche l'ultima attesa implicita non è richiesta .. qualcuno lo conferma. @ashishmishra
ihightower

1

se vuoi scorrere all'interno di una particolare vista / cornice (WebElement), devi solo sostituire "body" con un particolare elemento che intendi scorrere all'interno. ottengo quell'elemento tramite "getElementById" nell'esempio seguente:

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

questo è il caso su YouTube , ad esempio ...


1

La ScrollTo()funzione non funziona più. Questo è quello che ho usato e ha funzionato bene.

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

Solo questo metodo ha funzionato nel mio caso, non altri ha funzionato. Grazie.
ePandit

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

funziona per il mio caso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.