Cómo construir un Web Scraper con Python y Selenium

Robert Sfichi el 06 Jul 2021

Muchos desarrolladores optan por crear su propio raspador web en lugar de utilizar los productos disponibles. Si preguntas a la mayoría de ellos qué lenguaje de programación prefieren, lo más probable es que oigas Python un montón de veces.

Python se ha convertido en el favorito del público debido a su sintaxis permisiva y la abundancia de bibliotecas que simplifican el trabajo de web scraping. Hoy vamos a hablar de una de esas bibliotecas.

Esta guía cubrirá cómo empezar a extraer datos con Selenium y Python. Vamos a construir un script de Python que se conectará a un sitio web, raspar algunos datos, formatearlo bien, y almacenarlo en un archivo CSV.

Si quieres una visión más general de cómo Python se puede utilizar en el web scraping, deberías consultar nuestra guía definitiva para construir un scraper con Python. Después, ¡vuelve aquí para que podamos entrar en más detalles!

Visión general del selenio

Tal y como se indica en el sitio web oficial de Selenium, Selenium es un conjunto de herramientas para automatizar los navegadores web que se introdujo por primera vez como herramienta para realizar pruebas entre navegadores.

La API construida por el equipo de Selenium utiliza el protocolo WebDriver para tomar el control de un navegador web, como Chrome o Firefox, y realizar diferentes tareas, como:

  • Rellenar formularios
  • Desplazamiento
  • Hacer capturas de pantalla
  • Pulsar botones

Ahora te estarás preguntando cómo se traduce todo esto en web scraping. Es muy sencillo.

La extracción de datos puede ser un verdadero dolor de cabeza a veces. Hoy en día, los sitios web se construyen como aplicaciones de página única, incluso cuando no es necesario. Aparecen CAPTCHAs con más frecuencia de la necesaria e incluso bloquean las IP de los usuarios normales.

En resumen, la detección de bots es una función muy frustrante que parece un error.

Selenium puede ayudar en estos casos entendiendo y ejecutando código Javascript y automatizando muchos procesos tediosos del web scraping, como desplazarse por la página, agarrar elementos HTML o exportar los datos obtenidos.

Instalación

Para mostrar el verdadero poder de Selenium y Python, vamos a raspar algo de información del subreddit /r/learnprogramming. Además de raspar datos, también te mostraré cómo se puede implementar el inicio de sesión. Ahora que tenemos una comprensión de la herramienta principal y el sitio web que vamos a utilizar, vamos a ver qué otros requisitos que necesitamos tener instalado:

1. Python. Utilizaremos Python 3.0. Sin embargo, siéntete libre de usar Python 2.0 haciendo ligeros ajustes. Puedes descargarlo e instalarlo desde aquí.

2. Paquete Selenium. Puede instalar el paquete Selenium utilizando el siguiente comando:

pip3 install selenio

3. Paquete Pandas. Se utilizará para extraer y almacenar los datos raspados en un archivo .csv. Por favor, ejecute el siguiente comando para instalarlo en su dispositivo.

pip3 install pandas

4. Paquete BeautifulSoup. Se utiliza para analizar documentos HTML y XML. Basta con ejecutar esta línea:

pip3 install beautifulsoup

5. Google Chrome. Consulta este enlace para saber más sobre cómo descargarlo e instalarlo.

6. Controlador Chrome. Nos ayudará a configurar el driver web para Selenium. Por favor, sigue este enlace para descargar e instalar la última versión de chromedriver. No olvides guardar la ruta donde lo instalaste.

Iniciar el navegador

Empecemos. Crea un nuevo archivo scraper.py e importa el paquete Selenium copiando la siguiente línea:

from selenium import webdriver

Ahora crearemos una nueva instancia de Google Chrome escribiendo:

driver = webdriver.Chrome(UBICACIÓN)

Sustituya UBICACIÓN por la ruta en la que se encuentra el controlador Chrome en su ordenador. Por favor, consulte la documentación de Selenium para encontrar la ruta más precisa para el controlador web, basado en el sistema operativo que está utilizando.

El último paso es acceder al sitio web del que queremos extraer los datos. En nuestro caso, se trata de https://www.reddit.com/r/learnprogramming/top/?t=month. Copia la siguiente línea en el archivo python recién creado:

driver.get("https://www.reddit.com/r/learnprogramming/top/?t=month")

Ejecutando el siguiente comando en una ventana de terminal:

python3 scraper.py

Ahora deberíamos tener una nueva instancia de Google Chrome abierta que especifique "Chrome está siendo controlado por un software de pruebas automatizado" en la parte superior de nuestra página.

Localización de datos específicos

Como probablemente ya te habrás dado cuenta, en este tutorial vamos a hacer scraping del subreddit /r/learnprogramming. Guardaremos el título de las entradas, el autor, el número de upvotes y los almacenaremos en un nuevo archivo .csv. Veamos dónde están situados en la página HTML y cómo podemos extraerlos.

Después de que Google Chrome haya cargado la página, hagamos clic con el botón derecho en cualquier entrada y pulsemos "Inspeccionar". Podemos encontrar el contenedor HTML del post bajo el nombre de clase _1oQyIsiPHYt6nx7VOmd1sz.

blog-image

También puedes ejecutar Google Chrome sin interfaz gráfica de usuario y registrar el contenido HTML de la página añadiendo un par de líneas de código. Estableceremos la opción headless en true para el controlador de Chrome (para eliminar la interfaz gráfica) y un tamaño de ventana de 1080 píxeles (para obtener el código HTML correcto para nuestro caso de uso).

Las dos últimas líneas de código salen de Chrome justo después de terminar de registrar el HTML de la página.

El nuevo archivo scraper.py tendrá el siguiente aspecto:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome("./chromedriver")
driver.get("https://www.reddit.com/r/learnprogramming/top/?t=month")

print(driver.page_source)
driver.quit()

Elemento Web

Un WebElement es un objeto Selenium que representa un elemento HTML. Como verás en el siguiente tutorial, podemos realizar muchas acciones sobre estos elementos. Algunas de ellas son:

  • Haciendo clic en él mediante el método .click()
  • Proporcionar texto a un elemento de entrada específico llamando al método .send_keys()
  • Lectura del texto de un elemento mediante element.text
  • Comprobación de si un elemento se muestra en la página llamando a .is_displayed() sobre él

Un ejemplo de Selenium en acción

Ahora que tenemos nuestro proyecto configurado, por fin podemos ponernos a raspar.

Inicio de sesión

Vamos a mostrar el poder de Selenium iniciando sesión en nuestra cuenta de Reddit y raspando los datos presentados anteriormente. Empecemos haciendo que Selenium haga clic en el botón de inicio de sesión situado en la parte superior de la página. Después de inspeccionar el HTML de la página, podemos ver que el nombre de clase del botón de inicio de sesión es _2tU8R9NTqhvBrhoNAXWWcP.

login_button = driver.find_element_by_class_name('_2tU8R9NTqhvBrhoNAXWWcP')
login_button.click()
blog-image

Esto abrirá el modal de login donde podemos ver las entradas de usuario y contraseña que tenemos que rellenar. Continuemos con las siguientes líneas:

driver.switch_to_frame(driver.find_element_by_class_name('_25r3t_lrPF3M6zD2YkWvZU'))

driver.find_element_by_id("loginUsername").send_keys('USERNAME')
driver.find_element_by_id("loginPassword").send_keys('PASSWORD')

driver.find_element_by_xpath("//button[@type='submit']").click()

Si inspeccionamos el elemento modal, podemos ver que su contenedor es un iframe. Por eso tenemos que cambiar a frame en la primera parte del código, ya que si seleccionamos las entradas sin él se producirá un error.

A continuación, obtenemos los elementos de entrada y les proporcionamos las credenciales adecuadas antes de pulsar el botón de envío. Esto nos devolverá a la página de /r/learnprogramming, ¡pero ahora ya hemos iniciado sesión y estamos listos para votar!

Hacer una captura de pantalla

Tomar una captura de pantalla usando Selenium y Python es bastante fácil. Todo lo que tienes que hacer es escribir el siguiente comando en el archivo scraper.py después de declarar el controlador web.

driver.save_screenshot('screenshot.png')

Es útil saber que puedes establecer el tamaño de la ventana de Google Chrome añadiendo las siguientes líneas de código:

from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--window-size=1920,1080")

Así es como se verá la captura de pantalla en nuestro caso:

blog-image

Extracción de datos

Como hemos dicho anteriormente, necesitamos obtener el título de los posts, el autor y el número de upvotes. Empecemos importando los paquetes BeautifulSoup y Pandas y creando tres arrays vacíos para cada tipo de información que necesitemos.

from bs4 import BeautifulSoup
import pandas as pd

titles = []
upvotes=[]
authors = []

Vamos a utilizar BeautifulSoup para analizar el documento HTML escribiendo las siguientes líneas:

content = driver.page_source
soup = BeautifulSoup(content, features="html.parser")

Después de inspeccionar con éxito el documento HTML y elegir los selectores adecuados, ahora vamos a obtener los títulos, upvotes y autores y asignarlos a la matriz correcta:

for element in soup.findAll('div', attrs={'class': '_1oQyIsiPHYt6nx7VOmd1sz'}):
title = element.find('h3', attrs={'class': '_eYtD2XCVieq6emjKBH3m'})
upvote = element.find('div', attrs={'class': '_3a2ZHWaih05DgAOtvu6cIo'})
author = element.find('a', attrs={'class': '_23wugcdiaj44hdfugIAlnX'})
titles.append(title.text)
upvotes.append(upvote.text)
authors.append(author.text)

Por último, almacenaremos la información en un archivo CSV utilizando el paquete Pandas que importamos anteriormente.

df = pd.DataFrame({'Post title': titles, 'Author': authors, 'Number of upvotes': upvotes})
df.to_csv('posts.csv', index=False, encoding='utf-8')

Ya está. Echemos un vistazo al archivo exportado:

blog-image

Parece tener toda la información que necesitamos.

Consejo adicional: A veces, necesitamos más datos de los que el sitio web proporciona en la primera carga. La mayoría de las veces, la acción de obtención de datos se dispara cuando el usuario se desplaza hacia abajo. Si necesita desplazarse hacia abajo para obtener más datos, puede utilizar el método .execute_script() de la siguiente manera:

scrollDown = "window.scrollBy(0,2000);"
driver.execute_script(scrollDown)

Reflexiones finales

Espero que hayas disfrutado creando el raspador web tanto como yo. Programar no siempre es divertido, pero crear pequeños scripts como este me recuerda a cuando estaba empezando, y hace que el proceso sea mucho más entretenido.

Aún así, el script que logramos construir en este tutorial no puede hacer mucho trabajo duro. Carece de un par de características esenciales que hacen que el web scraping sea impecable. Conectarse usando proxies móviles o residenciales y resolver CAPTCHAs son sólo un par de ellas.

Si buscas una forma más profesional de extraer datos, echa un vistazo a lo que WebScrapingAPI puede hacer y comprueba por ti mismo si hay alguna coincidencia. Hay un paquete gratuito, así que la única inversión son 30 minutos de tu atención.

Gracias por tomarse el tiempo de leer esto. ¡Feliz raspado!

Noticias y actualidad

Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

miniatura
GuíasCómo raspar datos de productos de Amazon: Guía completa de mejores prácticas y herramientas

Explore las complejidades del scraping de datos de productos de Amazon con nuestra guía en profundidad. Desde las mejores prácticas y herramientas como Amazon Scraper API hasta las consideraciones legales, aprenda a superar los desafíos, eludir los CAPTCHA y extraer información valiosa de forma eficiente.

Suciu Dan
avatar de autor
Suciu Dan
15 minutos de lectura
miniatura
GuíasTutorial de Scrapy Splash: Dominar el arte del scraping de sitios web renderizados en JavaScript con Scrapy y Splash

Aprenda a scrapear sitios web dinámicos con JavaScript utilizando Scrapy y Splash. Desde la instalación hasta la escritura de una araña, el manejo de la paginación y la gestión de las respuestas de Splash, esta completa guía ofrece instrucciones paso a paso tanto para principiantes como para expertos.

Ștefan Răcila
avatar de autor
Ștefan Răcila
6 min leer
miniatura
GuíasAprenda a eludir la detección de Cloudflare con el mejor navegador Selenium

Conozca cuál es el mejor navegador para eludir los sistemas de detección de Cloudflare mientras hace web scraping con Selenium.

Mihnea-Octavian Manolache
avatar de autor
Mihnea-Octavian Manolache
9 min leer