Artículo original escrito por Otávio Simões Silveira
Artículo original   https://www.freecodecamp.org/news/improve-web-scraping-with-selenium/
Traducido y adaptado por Andrés Torres

Cuando estás raspando datos de la web con Python, Selenium a menudo será una herramienta útil para emplear. Pese a ser originalmente diseñada para automatización de pruebas, sus capacidades de raspado web son también impresionantes.

Esto es debido a que Selenium puede hacer cosas que otras bibliotecas o entornos no pueden cuando recolectan datos: Acceder ha contenido JavaScript e interactuar con la página en básicamente cualquier forma que quieras.

Este artículo es acerca de la segunda capacidad – Interactuar con la página de la forma que quieras. Cubrirá tres temas útiles para proporcionarte más opciones cuando interactúes con un sitio web con el propósito de acceder a su contenido.

Y a pesar de que este artículo se centra en el Raspado Web, este es solo uno de los usos para estas sugerencias, puesto que puedes implementarlos para cualquier tarea en la que Selenium es útil.

Ante de empezar, una aclaración importante: Antes de empezar a raspar cualquier sitio web, asegúrate de verificar si el sitio te permite hacerlo. También es una buena práctica configurar tu raspado para no sobrecargar el servidor del sitio, ya que no intentamos causar ningún daño.

El raspado es divertido y una gran manera de obtener datos, pero necesita ser realizado de una forma correcta y legal.

Cómo marcar casillas de verificación

El proceso de raspado web no implica solo raspar datos. En ocasiones necesitas navegar por el sitio web para saber donde se encuentran los datos que buscas. Y cuando vas por el sitio web, puede ser necesario llenar algunos formularios, dar clic en uno o dos botones y marcar una casilla de verificación por ejemplo.

Marcar una casilla de verificación puede parecer una acción muy simple, pero puede ser un poco engañosa. Esto es debido a que puedes pensar que todo lo que necesitas hacer es localizar el elemento usando su Xpath y después usar el método click para acceder.

Y, sí, dependiendo del sitio web puede ser el caso – pero no es una regla. En la mayoría de websites, Selenium no reconocerá un cuadro de verificación como un botón en el que se puede hacer clic. Es decir, cuando intentas dar clic en él, aparecerá una excepción.

El funcionamiento de esto es localizar el elemento y usar un objeto ActionChains para mover el cursor a la casilla de verificación y luego dar clic en él. Mueve el cursor a la casilla de verificación (check box) y luego haz clic en él. Esta es la línea de código para hacerlo:

check_box = driver.find_element_by_xpath('Xpath')

actions = webdriver.ActionChains(driver)
actions.move_to_element_with_offset(check_box, -5, 5).perform()
actions.click().perform()

El método  move_to_element_with_offset  moverá el ratón a un elemento específico de en la página, relativo a su esquina superior izquierda.

El objetivo es tener el cursor alrededor de la mitad de la casilla de verificación. Para encontrar una distancia apropiada para el movimiento, ejecuta el código con el atributo size del elemento antes de correr el código completo.

check_box = driver.find_element_by_xpath('Xpath')
print(check_box.size)

El resultado debe lucir parecido a este:

{'height': 10, 'width': 10}

Y luego, después de que el cursor ha sido movido, solo necesitas dar un clic y la casilla de verificación aparecerá marcado.

Como manipular marcos (frames)

Puede que te hayas encontrado en una situación en que no puedes usar Selenium para encontrar un elemento en particular en la página web. Sin importar cuanto lo intentes– Usando el Xpath, o el nombre de clase, de cualquier forma –Continúas obteniendo errores.

Has revisado y no hay errores, además, tu código parece estar bien. ¿Cuál es el problema?

Nada está mal. Los datos que tú buscas recolectar o el elemento con el que tú buscas interactuar simplemente está en otro marco de la página. Usamos marcos de HTML para dividir la página en secciones de modo que cada carga una parte diferente del contenido.

Para arreglar el problema, solo necesitas cambiar al marco correcto antes de intentar interactuar con la página otra vez. Si sabes el nombre del marco, simplemente haz esto:

driver.switch_to.frame('mainIframe')

También puedes usar el índice del marco para hacer el cambio:

driver.switch_to.frame(0)

Si no sabes el nombre del marco o cuantos marcos hay en la página, la solución es encontrar todos los marcos en la página y luego imprimir el nombre de cada uno de ellos. Así:

frames = driver.find_elements_by_tag_name('iframe')
for frame in frames:
   print(frame.get_attribute('name'))

Para encontrar cuantos marcos hay en la página, solo imprime la longitud(len) de  frames.

print(len(frames))

Y ahora, siéntete libre de interactuar con la página y recolectar los datos que necesites.

Cómo cambiar tablas

Otra situación común que puedes estar enfrentando, es la siguiente; cuando navegas a través de un sitio web para recolectar datos, un botón automáticamente abre una nueva etiqueta. Cuando esto sucede, es importante saber como ir de una tabla a otra para obtener los datos que necesitas.

Afortunadamente, manejar tablas con Selenium no es un proceso complejo. Actualmente, es algo similar a manejar marcos.

Puedes usar un enfoque más rústico, usando dos objetos:  uno contiene la tabla actual y el otro contiene todas las tablas. Luego, solo tienes que iterar sobre el segundo, siendo la iteración diferente de la tabla actual que tú cambiaste.

current_tab = driver.current_window_handle

all_tabs = driver.window_handles
for tab in all_tabs:
   if tab!= current_tab:
       driver.switch_to.window(tab)

Pero si tienes más de dos tablas y quieres ser capaz de acceder a cualquiera de ellas en cualquier momento, existe un enfoque más elegante – y solo necesitarás mantener un registro del orden en el cual las tablas son abiertas.

Para este enfoque, no necesitas saber cuál es la tabla actual. Esto es debido a que puedes cambiar tablas solo seleccionando los índices correspondientes de la tabla que quieres mover al objeto con todas las tablas.

driver.switch_to.window(all_tabs[i])

Si deseas ir a través de todas las tablas de una sola vez, y recolectar datos en cada una de ellas, puedes simplemente iterar sobre todas las tablas también.

all_tabs = driver.window_handles
for tab in all_tabs:
   driver.switch_to.window(tab)

Sin embargo, si estás abriendo más tablas para raspar datos, y tienes muchos links por raspar, debes ser consciente que estás haciendo considerablemente más peticiones al sitio de lo usual. Esto es debido a que en cada link, estás abriendo dos o tres nuevas tablas.

En este caso, también querrás insertar algunas pausas aleatorias en tu código, con el propósito de no sobrecargar el servidor. También querrás tomar ventaja de un proveedor de proxy, como Enfática(una empresa comprometida con compartir información a través de artículos como este) para asegurarte que tu código seguirá corriendo siempre y cuando dejes páginas para el raspado.

Esto también te asegura que no serás bloqueado, y que tu conexión será protegida.

Conclusión

Espero que estas sugerencias de Selenium te ayuden hacer el raspado de datos más efectivo. Hay mucho más que puedes hacer, pero quería mantener esto relativamente corto.

Si estás interesado en más contenido como este, o tienes una pregunta, sugerencia o solo quieres mantenerte en contacto, siéntete libre de contactarme. Tal vez pueda haber una segunda parte pronto.