Ir al contenido

Introducción a Selenium en Python

13 mins· 0 · 0 ·
Python Selenium Webscraping
Autor
Jan Dimter
Sociologist from Universidad de Chile. Assistant researcher at IMFD.
Tabla de contenido

Cheatsheet - Lista de funciones #

Función Código
1. Iniciar el WebDriver
from selenium import webdriver
driver = webdriver.Firefox()
# driver = webdriver.Firefox(executable_path=r'ruta/a/tu/geckodriver')
2. Navegar a una página web
driver.get("https://www.emol.com/")
3. Localizar un elemento por ID
from selenium.webdriver.common.by import By
elem = driver.find_element(By.ID,'frase_busqueda')
4. Localizar un elemento por nombre
elem = driver.find_element(By.NAME,'frase_busqueda')
5. Localizar un elemento por clase CSS
elem = driver.find_element(By.CLASS_NAME,"frase_input_bus")
6. Localizar un elemento por selector CSS
elem = driver.find_element(By.CSS_SELECTOR,"#frase_busqueda")
7. Localizar un elemento por XPath
elem = driver.find_element(By.XPATH,'//*[@id="frase_busqueda"]')
8. Localizar varios elementos
elements = driver.find_elements(By.TAG_NAME,'h3')
9. Obtener el texto de un elemento
for element in elements:
    print(element.text)
9. Obtener un atributo de un elemento
elem = driver.find_element(
    By.ID, 'ucHomePage_cuNoticiasCentral_LinkTitulo'
)
attribute = elem.get_attribute('href')
10. Enviar teclas a un elemento
from selenium.webdriver.common.keys import Keys
elem = driver.find_element(By.ID,'frase_busqueda')
elem.send_keys("Bullying")
elem.send_keys(Keys.RETURN)
11. Hacer clic en un elemento
elem = driver.find_element(By.ID,'ingresarH')
elem.click()
12. Ejecutar un script de JavaScript
driver.execute_script("return document.title")
13. Esperar a que un elemento esté presente
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located(
        (By.ID, "listado-avisos")
    )
)
14. Cambiar entre ventanas o pestañas
# Abre una nueva pestaña
driver.execute_script("window.open('');")

# Cambia a la pestaña por índice
driver.switch_to.window(driver.window_handles[0])

# Navega a una nueva URL en la nueva pestaña
driver.get('https://www.google.com')

# Obtiene nombres de las pestañas
driver.window_handles

# Cambia a pestaña por nombre
driver.switch_to.window("9e01f567-cf4b-43ac-9598-70924d09c016")
15. Manejar cookies
# Obtener todas las cookies
driver.get_cookies()

# Agregar una cookie
driver.add_cookie({'name' : 'foo', 'value' : 'bar'})

# Eliminar una cookie
driver.delete_cookie('foo')
16. Cerrar el navegador
# Cierra la ventana actual
driver.close()
# Cierra todas las ventanas y finaliza la sesión de WebDriver
driver.quit()  

Introducción #

¿Qué es Selenium? #

Selenium es un marco de trabajo (framework) de código abierto que se utiliza para automatizar las pruebas de las aplicaciones web. Proporciona una forma de interactuar con los elementos web de una página de manera programática, es decir, puede hacer clic en botones, rellenar formularios, leer texto, entre otros, tal como lo haría un usuario humano. Es una herramienta que es ampliamente utilizada en la industria para realizar pruebas automatizadas en aplicaciones web, pero también puede ser utilizada para automatizar tareas repetitivas que se realizan a través de una interfaz web.

¿Por qué usar Selenium con Python? #

Python es un lenguaje de programación de alto nivel, interpretado, que se destaca por su sintaxis limpia y legible. Es muy fácil de aprender y, por lo tanto, una excelente opción para principiantes y expertos por igual. Al combinar Selenium con Python, puedes automatizar y probar aplicaciones web de manera rápida y eficiente.

Python también tiene una comunidad de desarrolladores fuerte y activa, lo que significa que hay muchas bibliotecas y marcos de trabajo que puedes usar junto con Selenium. Además, Selenium proporciona una API de Python que es fácil de usar y robusta.

Usos comunes de Selenium #

Selenium es mayormente conocido por su uso en pruebas de automatización para aplicaciones web. Aquí algunos usos comunes:

  • Pruebas de regresión: Para asegurarse de que los cambios recientes en el código no han roto las funcionalidades existentes. Pruebas funcionales: Para comprobar que las funciones de la aplicación funcionan como se espera.

  • Pruebas de aceptación: Para verificar si la aplicación cumple con los requisitos del cliente. Además de las pruebas, Selenium también puede ser útil para tareas de automatización web, como la extracción de datos de sitios web (web scraping).

Además de las pruebas, Selenium también puede ser útil para tareas de automatización web, como la extracción de datos de sitios web (web scraping).

Navegadores compatibles con Selenium #

Selenium es compatible con los navegadores web más populares, incluyendo Google Chrome, Mozilla Firefox, Safari, Internet Explorer, y Microsoft Edge. Cada navegador requiere un controlador específico para interactuar con él. En este tutorial, nos centraremos en el uso de Selenium con Firefox y su controlador correspondiente, GeckoDriver.

En el siguiente capítulo, te guiaremos a través de la preparación de tu entorno de desarrollo para comenzar a utilizar Selenium con Python y Firefox.

Preparación del entorno de desarrollo #

Instalación de Selenium WebDriver #

Para hacerlo, simplemente escribe pip install selenium en la consola. Este comando instalará el último paquete de Selenium en tu entorno virtual.

Instalación y configuración del driver de Firefox (GeckoDriver) #

Para que Selenium pueda interactuar con Firefox, necesitas instalar GeckoDriver, que es el driver que Selenium usa para conectarse a Firefox. Puedes descargarlo del sitio web oficial de GitHub de GeckoDriver. Asegúrate de descargar la versión que corresponde a tu sistema operativo y arquitectura.

Después de descargarlo, debes extraer el archivo y moverlo a una ubicación en tu PATH. Una opción común es moverlo al directorio /usr/local/bin en sistemas Unix o a la carpeta donde está instalado Python en sistemas Windows.

Una vez que hayas hecho esto, deberías poder ejecutar geckodriver --version en la consola y ver la versión que acabas de instalar. Ahora estás listo para empezar a usar Selenium con Python y Firefox.

Conceptos básicos de Selenium #

Entendiendo el DOM (Document Object Model) #

El DOM es una representación en árbol de todos los elementos de una página web. Cada página web tiene su propio DOM, y Selenium lo utiliza para interactuar con los elementos web. Entender cómo está estructurado el DOM de una página y cómo acceder a sus elementos es fundamental para trabajar con Selenium.

Selenium WebDriver: explicación y arquitectura #

Selenium WebDriver es el componente clave de Selenium que permite la interacción con el navegador. A través de una API sencilla, WebDriver puede emular todas las acciones que un usuario humano haría en un navegador, como hacer clic en botones, introducir texto y extraer contenido.

WebDriver utiliza un sistema de controladores para interactuar con los diferentes navegadores. Cada navegador tiene su propio controlador (por ejemplo, Firefox tiene GeckoDriver, Chrome tiene ChromeDriver, etc.). Cuando haces una llamada a la API de WebDriver, esta instrucción se envía al controlador correspondiente, que luego interactúa con el navegador.

Interactuando con el navegador #

Para empezar a interactuar con una página web, primero debes importar el controlador de Selenium correspondiente y crear una nueva instancia de navegador. En el caso de Firefox, harías algo como lo siguiente:

from selenium import webdriver
driver = webdriver.Firefox()

Una vez que tienes una instancia de navegador, puedes empezar a navegar por la web con el método get(). Por ejemplo, para ir a la página de Google, harías:

driver.get("https://www.google.com")

Localizando elementos #

Selenium proporciona varios métodos para localizar elementos en una página web. Estos elementos se pueden localizar por su ID, nombre, clase, selector de CSS, XPath, entre otros. Una vez que localizas un elemento, puedes interactuar con él (por ejemplo, hacer clic en él, introducir texto, leer su contenido, etc.).

Por ejemplo, si quisieras localizar la barra de búsqueda de Google (que tiene el nombre “q”) e introducir texto en ella, podrías hacer algo como esto:

from selenium.webdriver.common.keys import Keys
search_bar = driver.find_element(By.NAME,'q')

No todos los elementos estarán disponibles inmediatamente cuando cargas una página, especialmente en las páginas web modernas que cargan contenido de forma dinámica. En estos casos, es posible que necesites implementar alguna forma de espera hasta que los elementos estén disponibles.

Interacción con elementos de la web #

Elementos de entrada: Textbox, botones, checkboxes, radio buttons #

Selenium puede interactuar con varios tipos de elementos de entrada en una página web. Los métodos más comunes son send_keys() para enviar texto a un campo de texto y click() para hacer clic en un elemento.

search_bar.send_keys("Magíster en Data Science UAI")
search_bar.send_keys(Keys.RETURN)

# Hacer clic en un botón
button = driver.find_element(By.XPATH,'/html/body/div[3]/div[2]/form/div[1]/div[1]/div[2]/div/div[3]/div[2]')
button.click()

Selección de elementos en dropdowns y menús #

Para seleccionar un elemento de un menú desplegable, Selenium proporciona la clase Select. Esta clase tiene varios métodos para seleccionar elementos por su índice, valor o texto visible.

from selenium.webdriver.support.ui import Select
driver.get("https://tcchile.cl/busqueda/jurisprudencia.php")
select_element = driver.find_element(By.ID, "mat-select-0-panel")

# Ver algunas opciones
for i in select_element.options[10:15]:
    print(i.text)

select_element.select_by_visible_text("Código del Trabajo")

Trabajando con alertas y pop-ups #

Las alertas y pop-ups son cuadros de diálogo que aparecen en la pantalla y requieren una interacción del usuario. Selenium puede aceptar, ignorar o leer el contenido de estas alertas.

# Estas funciones asumen que existe una alerta/popup. En caso contrario generará error.

# Aceptar alerta
alert = driver.switch_to.alert
alert.accept()

# Ignorar alerta
alert.dismiss()

# Leer el contenido de la alerta
alert_text = alert.text

Manejo de ventanas y tabs múltiples #

Con Selenium puedes abrir nuevas pestañas o ventanas y cambiar entre ellas. Cada pestaña o ventana tiene un identificador único llamado handle. Puedes obtener todos los handles con driver.window_handles y cambiar a una pestaña o ventana específica con driver.switch_to.window(handle).

# Abrir nueva pestaña
driver.execute_script("window.open('');")

# Cambiar a la nueva pestaña
driver.switch_to.window(driver.window_handles[-1])

# Cambiar de nuevo a la pestaña original
driver.switch_to.window(driver.window_handles[0])

Navegación y esperas en Selenium #

Navegación #

Además de la navegación básica que hemos mencionado en capítulos anteriores, Selenium también proporciona métodos para navegar hacia atrás y hacia adelante en tu historial de navegación, así como para actualizar la página actual.

# Ir a una URL
driver.get("https://www.yahoo.com")

# Navegar hacia atrás
driver.back()

# Navegar hacia adelante
driver.forward()

# Refrescar la página
driver.refresh()

Esperas explícitas #

Las esperas explícitas son tu manera de decirle a Selenium que espere a que ocurra una condición específica antes de proceder con el código. Selenium proporciona la clase WebDriverWait junto con la clase expected_conditions para implementar las esperas explícitas.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver.get('https://www.laborum.cl/empleos-busqueda-data.html')

elem = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "listado-avisos")))

Esperas implícitas #

A diferencia de las esperas explícitas, donde esperas a que ocurra una condición específica, las esperas implícitas configuran un tiempo de espera que se aplicará por defecto cuando estás tratando de encontrar elementos.

# Configurar una espera implícita de 10 segundos
driver.implicitly_wait(10)

# Ahora, cada vez que intentas encontrar un elemento, Selenium esperará hasta 10 segundos antes de lanzar una excepción
element = driver.find_element(By.ID, "listado-avisos")

Las esperas explícitas y las esperas implícitas no deberían mezclarse en el mismo script de prueba, ya que podrían causar resultados impredecibles.

Esperas con sleep #

Finalmente, aunque no se recomienda, también puedes hacer que tu script de prueba duerma por un tiempo fijo con el método time.sleep(). Sin embargo, este método no es preferido porque hace que tu prueba se detenga incondicionalmente por el tiempo especificado, incluso si la condición que estás esperando ya ha ocurrido.

import time

# Hacer que el script duerma por 5 segundos
time.sleep(5)

Estrategias de optimización y manejo de fallos #

Optimización de la carga de datos #

A veces, puedes querer optimizar la carga de datos en tus pruebas de Selenium para hacerlas más rápidas y consumir menos ancho de banda. Una forma común de hacer esto es deshabilitando la carga de imágenes. Esto se puede lograr utilizando las preferencias del perfil de Firefox en Selenium.

from selenium import webdriver

firefox_profile = webdriver.FirefoxProfile()
firefox_profile.set_preference('permissions.default.image', 2)

driver = webdriver.Firefox(firefox_profile=firefox_profile)
driver.get('https://www.laborum.cl/empleos-busqueda-data.html')

Manejo de fallos de conexión a Internet #

Las pruebas de Selenium dependen de tener una conexión a Internet para interactuar con las aplicaciones web. Sin embargo, la conexión a Internet puede ser inestable y puede caerse en cualquier momento. Para manejar estos casos, puedes implementar un manejo de excepciones en tus pruebas para volver a intentarlo cuando falla una acción de Selenium.

A continuación un ejemplo (imperfecto):

from selenium.common.exceptions import WebDriverException
import time

def safe_get(driver, url, attempts=3, delay=5):
    for i in range(attempts):
        try:
            driver.get(url)
            return
        except WebDriverException:
            if i < attempts - 1:  # i es base 0, así que esto no se ejecutará en la última iteración
                time.sleep(delay)  # Esperar un poco antes de volver a intentarlo
                continue
            else:
                raise

# Ahora puedes usar safe_get en lugar de driver.get
safe_get(driver, "https://www.laborum.cl/empleos-busqueda-data.html")

Uso de Selenium para Web Scraping #

Introducción al Web Scraping con Selenium #

El Web Scraping es una técnica utilizada para extraer información de sitios web. Consiste en hacer solicitudes HTTP a las URL de los sitios web y luego analizar el HTML de las páginas web para obtener los datos deseados.

Selenium, que originalmente se diseñó para probar aplicaciones web, se ha convertido en una herramienta popular para el Web Scraping. A diferencia de otras bibliotecas de Python para el Web Scraping como Beautiful Soup o Scrapy, que sólo pueden analizar el HTML estático de las páginas web, Selenium puede interactuar con el JavaScript de las páginas web y por lo tanto puede utilizarse para extraer datos de las páginas web que dependen del JavaScript.

Además, con Selenium, puedes simular la interacción del usuario con la página web, como hacer clic en botones o llenar y enviar formularios, lo cual puede ser útil para extraer datos de páginas web que requieren interacción del usuario.

Navegando a través de páginas #

Algunas veces, es posible que necesites trabajar con URL dinámicas, es decir, URL que cambian dependiendo de ciertos parámetros. Por ejemplo, en un sitio web de comercio electrónico, la URL de la página de un producto puede incluir el ID del producto. Para trabajar con este tipo de URL, puedes utilizar las capacidades de formateo de strings de Python.

product_id = "123"
url = f"https://www.example.com/products/{product_id}"
driver.get(url)

Localizando elementos en la página #

Una vez que has navegado a la página web, el siguiente paso es localizar los elementos de los que deseas extraer datos. Selenium proporciona varios métodos para localizar elementos, como find_element_by_name, find_element_by_id, find_element_by_class_name, find_element_by_css_selector y find_element_by_xpath.

Por ejemplo, supongamos que quieres extraer el título de una página. En HTML, el título suele estar en un elemento <h1>, así que podrías hacerlo de la siguiente manera:

driver.get('https://es.wikipedia.org/wiki/Mandorla')
title_element = driver.find_element(By.ID, "listado-avisos")
title_text = driver.find_element(By.TAG_NAME,'h1').text
title_text

A veces, puedes querer localizar varios elementos a la vez. Por ejemplo, podrías querer extraer todos los nombres de productos en una página de categoría de un sitio web de comercio electrónico. Para hacerlo, puedes usar el método find_elements_by_tag_name (fíjate en el plural “elements”):

product_elements = driver.find_elements(By.TAG_NAME,'h2')
product_names = [element.text for element in product_elements]
product_names

Para localizar elementos más complejos, puedes usar selectores de CSS o XPath. Los selectores de CSS son una forma de seleccionar elementos basándose en su id, clase, atributos, y relación con otros elementos. XPath, por otro lado, permite seleccionar elementos basándose en una expresión que representa su ubicación en el árbol del documento.

Por ejemplo, para seleccionar el primer producto en una lista de productos, podrías hacerlo así:

# Con un selector de CSS
first_product_element = driver.find_element_by_css_selector('ul.products li:first-child')

# Con XPath
first_product_element = driver.find_element_by_xpath('//ul[@class="products"]/li[1]')

Interactuando con elementos de la página #

Además de extraer datos, con Selenium también puedes interactuar con los elementos de la página. Esto puede ser útil para las páginas que requieren interacción del usuario para mostrar los datos que quieres extraer.

Por ejemplo, podrías llenar y enviar un formulario de esta manera:

driver = webdriver.Firefox()
driver.get("https://www.browserstack.com/users/sign_in")

username_field = driver.find_element(By.ID,'user_email_login')
username_field.send_keys('miusuario@yahoo.com')

password_field = driver.find_element(By.ID,'user_password')
password_field.send_keys('clave123')

driver.find_element(By.ID,'user_submit').click()

Trabajando con páginas de JavaScript #

Muchas páginas web modernas utilizan JavaScript para cargar y actualizar dinámicamente el contenido de la página. Esto puede ser un problema para las herramientas de web scraping que sólo pueden analizar HTML estático. Pero con Selenium, puedes interactuar con las páginas de JavaScript igual que un usuario humano.

Un aspecto importante al trabajar con páginas de JavaScript es que debes esperar a que el JavaScript se cargue antes de interactuar con los elementos de la página. Para hacerlo, puedes usar las esperas explícitas de Selenium:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

# Espera hasta 10 segundos a que se cargue el elemento con ID "dynamic-content"
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "dynamic-content"))
)

También puedes ejecutar tu propio código JavaScript en la página usando el método execute_script:

driver.execute_script("alert('Hola, mundo!');")

Manejo de paginación #

La paginación es una técnica comúnmente utilizada en las páginas web para dividir el contenido en varias páginas. Con Selenium, puedes interactuar con los elementos de paginación para navegar entre las páginas.

Para detectar cuándo has llegado al final de las páginas, puedes comprobar si el botón “Siguiente” está deshabilitado:

driver.get('https://rastro.com/avisos/bicicletas/')

next_button = driver.find_element(By.XPATH,'/html/body/div[5]/div/div[1]/div[3]/div[1]/div/nav/ul/li[2]/a')
if not next_button.is_enabled():
    print("Llegamos al final de las páginas.")

Trabajando con cookies #

Las cookies son una forma de almacenar información en el navegador del usuario. Con Selenium, puedes leer, configurar y borrar cookies.

Para leer todas las cookies, puedes usar el método get_cookies.

cookies = driver.get_cookies()
for cookie in cookies:
    print(cookie['name'], cookie['value'])

Para configurar una cookie, puedes usar el método add_cookie.

driver.add_cookie({'name': 'my_cookie', 'value': 'my_value'})

Para borrar una cookie, puedes usar el método delete_cookie.

driver.delete_cookie('my_cookie')

Relacionados

Introducción a Beautifulsoup en Python
5 mins· 0 · 0
Python Beautifulsoup Webscraping
BeautifulSoup es una biblioteca de Python que permite extraer información de archivos HTML y XML. Fue diseñada para hacer que el webscraping, o la extracción de datos de sitios web, sea más accesible y fácil de hacer. BeautifulSoup convierte los archivos HTML y XML en árboles de parseo, que son estructuras de datos que representan la jerarquía de los elementos en el archivo.
Introducción a R & Rstudio
10 mins· 0 · 0
R Rstudio Languages
R fue desarrollado principalmente como un lenguaje para el análisis estadístico y contiene una amplia variedad de funciones y paquetes para estadísticas tradicionales y modernas.
Learning to cluster urban areas: two competitive approaches and an empirical validation
papers Urban Clustering
Urban clustering detects geographical units that are internally homogeneous and distinct from their surroundings. It has applications in urban planning, but few studies compare the effectiveness of different methods. We study two techniques (GMMs), which operate on spatially distributed data, and Deep Modularity Networks (DMONs), which work on attributed graphs of proximal nodes.
comments powered by Disqus