Quiero raspar todos los datos de una página implementada por un desplazamiento infinito. El siguiente código de Python funciona.
for i in range(100):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
Esto significa que cada vez que me desplazo hacia abajo, necesito esperar 5 segundos, que generalmente es suficiente para que la página termine de cargar los contenidos recién generados. Pero, esto puede no ser eficiente en el tiempo. La página puede terminar de cargar los nuevos contenidos en 5 segundos. ¿Cómo puedo detectar si la página terminó de cargar los nuevos contenidos cada vez que me desplazo hacia abajo? Si puedo detectar esto, puedo desplazarme hacia abajo nuevamente para ver más contenido una vez que sepa que la página terminó de cargarse. Esto es más eficiente en el tiempo.
python
selenium
execute-script
apogne
fuente
fuente
Respuestas:
El
webdriver
va a esperar a que cargue una página por defecto a través de.get()
método.Como puede estar buscando algún elemento específico como dijo @ user227215, debe usar
WebDriverWait
para esperar un elemento ubicado en su página:Lo he usado para verificar alertas. Puede utilizar cualquier otro tipo de método para encontrar el localizador.
EDITAR 1:
Debo mencionar que
webdriver
esperará a que se cargue una página por defecto. No espera la carga dentro de los marcos o las solicitudes de ajax. Significa que cuando lo use.get('url')
, su navegador esperará hasta que la página esté completamente cargada y luego irá al siguiente comando en el código. Pero cuando publica una solicitud de ajax,webdriver
no espera y es su responsabilidad esperar la cantidad de tiempo adecuada para que se cargue la página o parte de ella; entonces hay un módulo llamadoexpected_conditions
.fuente
browser.find_element_by_id('IdOfMyElement')
provoca unNoSuchElementException
ser levantado. La documentación dice que pasar una tupla que tiene este aspecto:(By.ID, 'IdOfMyElement')
. Mira mi respuestaclick()
), leer texto, etc. Tenía la impresión errónea de que solo provocó una espera, después de lo cual aún tenía que encontrar el elemento. Si hace una espera, luego se encuentra un elemento de búsqueda, el selenio generará un error porque intenta encontrar el elemento mientras la espera anterior aún se está procesando (con suerte, eso tiene sentido). La conclusión es que no necesita encontrar el elemento después de usar WebDriverWait: ya es un objeto.Intentando pasar
find_element_by_id
al constructor porpresence_of_element_located
(como se muestra en la respuesta aceptada ) provocóNoSuchElementException
que se elevara. Tuve que usar la sintaxis en el comentario de los fragmentos :Esto coincide con el ejemplo en la documentación . Aquí hay un enlace a la documentación de By .
fuente
EC.presence_of_element_located((By.XPATH, "//*[@title='Check All Q1']"))
By
objeto.Encuentra a continuación 3 métodos:
readyState
Página de comprobación readyState (no confiable):
id
Comparando nuevos identificadores de página con el anterior:
staleness_of
Utilizando el
staleness_of
método:Para más detalles, consulte el blog de Harry .
fuente
self.driver.execute_script('return document.readyState;')
no es confiable? Parece que funciona perfectamente para mi caso de uso, que está esperando que se cargue un archivo estático en una nueva pestaña (que se abre a través de JavaScript en otra pestaña en lugar de .get ()).Como se menciona en la respuesta de David Cullen , siempre he visto recomendaciones para usar una línea como la siguiente:
Me resultó difícil encontrar en algún lugar todos los posibles localizadores que se puedan utilizar con el
By
, por lo que pensé que sería útil proporcionar la lista aquí. Según Web Scraping with Python de Ryan Mitchell:fuente
Desde selenium / webdriver / support / wait.py
fuente
En una nota al margen, en lugar de desplazarse hacia abajo 100 veces, puede verificar si no hay más modificaciones en el DOM (estamos en el caso de que la parte inferior de la página esté cargada AJAX)
fuente
¿Lo has intentado
driver.implicitly_wait
? Es como una configuración para el controlador, por lo que solo se llama una vez en la sesión y básicamente le dice al controlador que espere la cantidad de tiempo dada hasta que se pueda ejecutar cada comando.Entonces, si establece un tiempo de espera de 10 segundos, ejecutará el comando lo antes posible, esperando 10 segundos antes de que se dé por vencido. He usado esto en escenarios similares de desplazamiento hacia abajo, así que no veo por qué no funcionaría en su caso. Espero que esto sea útil.
Para poder corregir esta respuesta, tengo que agregar un nuevo texto. Asegúrese de usar una 'w' minúscula
implicitly_wait
.fuente
¿Qué hay de poner WebDriverWait en el bucle While y capturar las excepciones?
fuente
Aquí lo hice usando una forma bastante simple:
fuente
Puede hacerlo muy simple con esta función:
y cuando desee hacer algo después de completar la carga de la página, puede usar:
fuente