¿Cómo puedo desplazar una página web usando selenium webdriver en python?

132

Actualmente estoy usando selenium webdriver para analizar a través de la página de amigos de usuarios de Facebook y extraer todos los identificadores del script AJAX. Pero necesito desplazarme hacia abajo para obtener todos los amigos. ¿Cómo puedo desplazarme hacia abajo en Selenium? Estoy usando python

usuario2523364
fuente
2
posible duplicado de Cómo desplazarse por la página con selenio
Louis
driver.execute_script (f "window.scrollTo (0, {2 ** 127});")
AturSams

Respuestas:

264

Puedes usar

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

donde Y es la altura (en un monitor fullhd es 1080). (Gracias a @lukeis)

También puedes usar

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

para desplazarse al final de la página.

Si desea desplazarse a una página con carga infinita , como las de redes sociales, Facebook, etc. (gracias 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

otro método (gracias a Juanse) es seleccionar un objeto y

label.sendKeys(Keys.PAGE_DOWN);
OWADVL
fuente
1
Excelente, ¿puedes explicar un poco sobre scrollHeightqué significa y cómo funciona en general?
Jason Goal
¿Cómo utilizarías la variable "last_height"? Tengo algo similar en mi código y el navegador se está desplazando hacia abajo. Sin embargo, cuando miro los datos que estoy raspando, solo raspa los datos de la primera página k veces, siendo "k" la cantidad de veces que el navegador se desplaza hacia abajo.
Peter Lenaers
72

Si desea desplazarse hacia abajo hasta la parte inferior de la página infinita (como linkedin.com ), puede usar este código:

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

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

Cuong Tran
fuente
Esto es genial. Para cualquiera que esté tratando de usar esto en instagram, es posible que primero deba presionar el botón "Cargar más" con ActionChains, luego aplicar la solución de Cuong Tran ... al menos eso fue lo que funcionó para mí.
Mwspencer el
¡Gracias por la respuesta! Lo que me gustaría hacer es desplazarme, por ejemplo, en instagram a la parte inferior de la página, luego tomar todo el html de la página. ¿Hay una función en selenio donde podría dar last_height como entrada y obtener toda la página html, después de desplazarme al final?
Swan87
2
El SCROLL_PAUSE_TIMEvaría, me lleva alrededor de 2 segundos.
ssi-anik
21

mismo método que se muestra aquí :

en python solo puedes usar

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

(Y es la posición vertical a la que desea desplazarse)

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

element.location_once_scrolled_into_view

Esto ayudó cuando estaba tratando de acceder a un 'li' que no era visible.

premonición
fuente
'find_element_by_xpath' es una función de controlador o qué, el '.location_once_scrolled_into_view' devuelve el error NoSuchElementException: Mensaje: no existe ese elemento: No se puede ubicar el elemento: {"método": "xpath", "selector": "// * [@ id = "línea de tiempo-popurrí"] / div / div [2] / div [1] "}
Walid Bousseta
Solo una cosa más. La razón por la que location_once_scrolled_into_viewdebería llamarse sin () es que location_once_scrolled_into_viewes un Python property. vea el código fuente aquí: selenium / webelement.py en d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ / selenium
DataAlchemist
10

Para mi propósito, quería desplazarme más hacia abajo, teniendo en cuenta la posición de las ventanas. Mi solución fue similar y utilizadawindow.scrollY

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

que irá a la posición actual de desplazamiento y + 200

Nick Brady
fuente
8

Así es como se desplaza hacia abajo en la página web:

driver.execute_script("window.scrollTo(0, 1000);")
sahaja nadendla
fuente
7

La forma más fácil que encontré para resolver ese problema fue seleccionar una etiqueta y luego enviar:

label.sendKeys(Keys.PAGE_DOWN);

¡Espero que funcione!

Juanse
fuente
6

Ninguna de estas respuestas funcionó para mí, al menos no para desplazarse hacia abajo en una página de resultados de búsqueda de Facebook, pero encontré después de muchas pruebas esta solución:

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
Bajo dee
fuente
Funciona, pero muy lento (al menos para mí). He descubierto que si se establece SCROLL_PAUSE_TIMEen stackoverflow.com/a/27760083/7326714 a 2, funciona muy bien y se desplaza hacia abajo a 100 veces más rápido.
LucSpan
6

Al trabajar con youtube, los elementos flotantes dan el valor "0" como la altura del desplazamiento, así que en lugar de usar "return document.body.scrollHeight", intente usar este "return document.documentElement.scrollHeight" y ajuste el tiempo de pausa de desplazamiento según su internet De lo contrario, se ejecutará solo una vez y luego se romperá después de eso.

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
Vinay Verma
fuente
5

Estaba buscando una manera de desplazarme por una página web dinámica y detenerme automáticamente una vez que se llega al final de la página, y encontré este hilo.

La publicación de @Cuong Tran , con una modificación principal, fue la respuesta que estaba buscando. Pensé que otros podrían encontrar útil la modificación (tiene un efecto pronunciado sobre cómo funciona el código), de ahí esta publicación.

La modificación consiste en mover la declaración que captura la última altura de la página dentro del bucle (para que cada verificación se compare con la altura de la página anterior).

Entonces, el código a continuación:

Desplaza continuamente hacia abajo una página web dinámica ( .scrollTo()), solo se detiene cuando, para una iteración, la altura de la página permanece igual.

(Hay otra modificación, donde la declaración de ruptura está dentro de otra condición (en caso de que la página se 'pegue') que se puede eliminar).

    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
Splarty
fuente
5

Este código se desplaza hacia abajo pero no requiere que esperes cada vez. Se desplazará continuamente y luego se detendrá en la parte inferior (o tiempo de espera)

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

Esto es mucho más rápido que esperar 0.5-3 segundos cada vez por una respuesta, cuando esa respuesta podría tomar 0.1 segundos

AlbertWolfgang
fuente
3

desplazarse cargando páginas. Ejemplo: medio, quora, etc.

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()
ashishmishra
fuente
1
¿debería driver.quit () estar fuera del bloque while o no? y también no se requiere la última espera implícita ... alguien confirma por favor. @ashishmishra
ihightower
1

si desea desplazarse dentro de una vista / marco particular (WebElement), lo que solo necesita hacer es reemplazar "cuerpo" con un elemento particular dentro del cual desea desplazarse. obtengo ese elemento a través de "getElementById" en el siguiente ejemplo:

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

este es el caso en YouTube , por ejemplo ...

Furkan Unluturk
fuente
1

La ScrollTo()función ya no funciona. Esto es lo que usé y funcionó bien.

driver.execute_script("document.getElementById('mydiv').scrollIntoView();")
MoKG
fuente
Solo este método funcionó en mi caso, no otro funcionó. Gracias.
ePandit
0
driver.execute_script("document.getElementById('your ID Element').scrollIntoView();")

Está funcionando para mi caso.

Long Lê Hoàng
fuente