Desarrollo de un scraper web básico en Python: Extracción de datos de sitios web
En el mundo de análisis de datos, la recopilación de datos es una tarea esencial. Sin embargo, en muchas ocasiones, obtener los datos necesarios para nuestro análisis puede ser un desafío. Es aquí donde entra en juego el web scraping, que nos permite extraer datos de sitios web de forma automatizada y rápida.
En este artículo, haremos un recorrido sobre cómo desarrollar un scraper web básico utilizando Python y cómo extraer datos de sitios web sin la necesidad de hacerlo manualmente.
Lo primero que debemos hacer es definir los objetivos de nuestra herramienta de scraping. Para esto, debemos tener en cuenta algunos factores, como los datos que necesitamos obtener, el sitio web del que los extraeremos, la frecuencia de actualización de los datos, entre otros.
Una vez definidos nuestros objetivos, necesitamos seleccionar las herramientas adecuadas para el scraping. Python dispone de varias librerías para trabajar en esta tarea, siendo las principales Beautiful Soup y Scrapy. En este artículo, utilizaremos Beautiful Soup por ser una herramienta sencilla y versátil para extraer datos de sitios web.
Ahora, definiremos el proceso de extracción de datos. En resumen, nuestra herramienta deberá seguir los siguientes pasos:
1. Descargar el contenido HTML de la página web seleccionada.
import requests
page = requests.get("https://www.example.com")
2. Analizar el HTML con Beautiful Soup
Una vez que hemos descargado el contenido HTML de la página, necesitamos utilizar Beautiful Soup para analizarlo y extraer solo los datos que nos interesan. Para esto, definiremos los elementos HTML que deseamos extraer como un objeto Beautiful Soup.
from bs4 import BeautifulSoup
soup = BeautifulSoup(page.content, 'html.parser')
3. Identificar los elementos HTML que deseamos extraer
Ahora que hemos definido el objeto Beautiful Soup, debemos identificar los elementos HTML que queremos extraer. Para esto, podemos utilizar las etiquetas HTML, clases, id, entre otros elementos.
results = soup.find_all('h3', class_='title')
4. Procesar y guardar los datos
Finalmente, procesamos y guardamos los datos extraídos en algún formato, como un archivo CSV o incluso una base de datos.
for result in results:
title = result.text.strip()
link = result.a['href']
print(title, link)
Es importante tener en cuenta que en algunos casos puede ser necesario solicitar permiso para utilizar técnicas de scraping en sitios web, ya que pueden violar los términos y condiciones de un sitio web.
El web scraping es una técnica útil y esencial en el análisis de datos, que nos permite extraer datos de sitios web de forma rápida y automática. Python dispone de herramientas como Beautiful Soup que nos permiten llevar a cabo esta tarea con facilidad. Sin embargo, debemos tener en cuenta los objetivos de nuestro scraping, las herramientas adecuadas y adquirir los permisos necesarios para realizar esta técnica.
Comenzamos con la instalación de las librerías necesarias en nuestro entorno virtual
Para empezar, necesitamos crear un entorno virtual para nuestro proyecto. Esto nos permitirá trabajar con un entorno limpio y separado del resto de nuestras instalaciones de Python. Podemos utilizar la herramienta virtualenv para lograr esto.
Una vez instalado, abrimos nuestra terminal y escribimos el siguiente comando para crear el entorno virtual:
virtualenv scraper_env
Esto creará una carpeta llamada scraper_env con todo lo necesario para trabajar en nuestro proyecto. Ahora necesitamos activar el entorno virtual con el siguiente comando:
source scraper_env/bin/activate
Después de esto, debemos ver el nombre del entorno virtual en nuestra terminal, indicando que estamos trabajando dentro de él. En nuestro caso, debería decir “(scraper_env)”.
Ahora que tenemos nuestro entorno virtual activado, podemos empezar a instalar las librerías necesarias. En este caso, vamos a utilizar BeautifulSoup y requests. Estas librerías nos permitirán hacer la extracción de datos de los sitios web.
Para instalar las librerías, simplemente debemos utilizar pip, el gestor de paquetes de Python. Escribimos los siguientes comandos:
pip install beautifulsoup4
pip install requests
Después de esto, las librerías estarán instaladas y listas para utilizar. Podemos verificar que se han instalado correctamente utilizando el siguiente comando:
pip list
Esto nos mostrará una lista de todas las librerías instaladas en nuestro entorno virtual, incluyendo las que acabamos de instalar.
Para instalar las librerías necesarias para nuestro proyecto de scraping web en Python, debemos crear un entorno virtual utilizando virtualenv, activarlo con “source scraper_env/bin/activate”, e instalar las librerías utilizando pip con “pip install beautifulsoup4” y “pip install requests”. Con esto, estaremos listos para empezar a escribir nuestro scraper web básico en Python y extraer datos de sitios web de manera efectiva.
Identificamos los elementos a extraer de la página web objetivo para hacer un plan de extracción
En este punto de nuestro proyecto, nos toca analizar la página web que queremos extraer para identificar los elementos que necesitamos. Para hacer esto, es importante tener en cuenta que cada sitio web es único y los elementos que queremos extraer pueden variar de uno a otro.
El primer paso es seleccionar la página que queremos extraer. En nuestro caso, utilizaremos un sitio web dedicado a la venta de libros y buscaremos extraer información como su título, autor, precio y descripción.
Para identificar los elementos que necesitamos, podemos utilizar el inspector de elementos en nuestro navegador. Al abrir el inspector, podemos hacer clic en cualquier elemento en la página para ver su código HTML correspondiente.
Por ejemplo, si hacemos clic en el título de un libro, podemos ver cómo se ve su etiqueta HTML. En nuestro caso, podríamos encontrar algo como esto:
<h2 class="book-title">El Gran Gatsby</h2>
Utilizando este método, podemos identificar fácilmente todos los elementos que necesitamos de la página. En el siguiente ejemplo, podemos ver cómo obtener el título, autor y precio usando BeautifulSoup, una librería de Python para parsear HTML:
from bs4 import BeautifulSoup
import requests
url = 'https://www.example.com/books/the-great-gatsby'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.find('h2', class_='book-title').text
author = soup.find('p', class_='author').text
price = soup.find('span', class_='price').text
Como se puede ver en el código, utilizamos las etiquetas HTML que ya habíamos identificado para extraer los datos de la página y almacenarlos en variables.
Para identificar los elementos que necesitamos de una página web, podemos utilizar el inspector de elementos en nuestro navegador. Una vez que tenemos una lista de elementos, podemos utilizar una librería como BeautifulSoup para parsear el HTML y extraer los datos necesarios. Con esto podemos hacer un plan de extracción que nos permita obtener la información requerida de manera efectiva.
Creamos una función que nos permita acceder a la página web y descargar el HTML
Desarrollar un scraper puede parecer complejo, pero la verdad es que no es tan difícil como parece. La clave está en entender cómo funcionan las páginas web y qué herramientas podemos utilizar para extraer la información que necesitamos.
En este tutorial vamos a utilizar Python y la librería BeautifulSoup para desarrollar un scraper básico que nos permita extraer información de una página web. Comenzaremos creando una función que nos permita acceder a la página web y descargar el HTML. Esta es la base de todo scraper, ya que para extraer información necesitamos primero descargar el código HTML de la página.
Para empezar, vamos a importar las librerías necesarias:
import requests
from bs4 import BeautifulSoup
La librería requests nos permite acceder a páginas web y descargar su contenido. La librería BeautifulSoup nos ayuda a analizar el código HTML y extraer la información que necesitamos.
Ahora, vamos a crear nuestra función para descargar el HTML de la página web:
def get_html(url):
response = requests.get(url)
html = response.content
return html
La función toma como argumento la URL de la página web que queremos descargar. Utilizamos la función requests.get()
para acceder a la página y guardamos la respuesta en la variable response
. Luego, utilizamos la propiedad content
de la respuesta para obtener el HTML de la página.
Finalmente, devolvemos el HTML con la instrucción return html
.
Para probar nuestra función, podemos agregar lo siguiente al final de nuestro archivo:
url = 'https://www.example.com'
html = get_html(url)
print(html)
Esto debería imprimir en la consola el código HTML de la página https://www.example.com
.
Hemos creado una función que nos permite acceder a una página web y descargar su contenido HTML. Esto es la base de todo scraper, ya que para extraer información necesitamos primero descargar el HTML de la página. En el próximo paso, utilizaremos la librería BeautifulSoup para analizar el HTML y extraer la información que necesitamos.
Utilizamos técnicas para limpiar el HTML y obtener solo los datos relevantes
Al momento de extraer datos de un sitio web utilizando un scraper en Python, es común que obtengamos más información de la que necesitamos. Es decir, no solo se extraen los datos que buscamos, sino también etiquetas HTML, enlaces, imágenes y otros elementos que no nos interesan. Por esta razón, es importante utilizar algunas técnicas para limpiar el HTML y obtener solamente los datos relevantes.
Una de las formas más comunes de limpiar el HTML es utilizando la librería BeautifulSoup. Esta librería nos permite analizar y extraer datos de páginas web de una manera mucho más sencilla que utilizando solamente expresiones regulares. La idea es seleccionar los elementos HTML que contienen la información que buscamos y eliminar todo el resto.
Por ejemplo, si estamos extrayendo información de una página web que contiene noticias, es probable que la información que nos interesa esté dentro de etiquetas con una clase específica. En este caso, podemos utilizar la función find_all de BeautifulSoup para seleccionar todos los elementos que cumplen con esa condición y luego separar el texto de las etiquetas HTML utilizando la función get_text.
from bs4 import BeautifulSoup
import requests
url = 'https://www.ejemplo.com'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# Selección de elementos HTML
noticias = soup.find_all('div', {'class': 'noticia'})
# Extracción de texto
for noticia in noticias:
titulo = noticia.find('h2').get_text()
cuerpo = noticia.find('p').get_text()
print(titulo)
print(cuerpo)
Otra técnica importante es la eliminación de etiquetas HTML innecesarias utilizando regex. El paquete re de Python nos permite buscar patrones dentro del texto y reemplazarlos por otro string. Podemos utilizar esto para eliminar etiquetas HTML, líneas en blanco y otros elementos que no nos interesan.
import re
texto_html = '<h1>Este es un título</h1>\n<p>Este es un párrafo con <strong>negritas</strong> y <em>cursivas</em>.</p>'
# Eliminación de etiquetas HTML
texto_sin_html = re.sub(r'<.*?>', '', texto_html)
# Limpieza de líneas en blanco
texto_sin_html = re.sub(r'\n+', '\n', texto_sin_html)
print(texto_sin_html)
La limpieza de datos es un proceso crítico en el desarrollo de scrapers web ya que nos permite obtener la información que buscamos de una manera más eficiente y reduce la cantidad de datos innecesarios que debemos procesar. Utilizando las técnicas adecuadas, podemos obtener datos limpios y listos para ser utilizados en nuestras aplicaciones.
Guardamos los datos obtenidos en un archivo CSV o en una base de datos
Una vez que hemos extraído los datos deseados de una página web, necesitamos almacenarlos en algún lugar para poder trabajar con ellos. En ocasiones, puede ser suficiente simplemente mostrarlos en pantalla, pero en otros casos, necesitamos guardarlos en un archivo o en una base de datos para su posterior análisis.
Una opción comúnmente utilizada es el formato CSV, que es un tipo de archivo que se utiliza para almacenar datos tabulares. En Python, podemos utilizar la librería csv
para trabajar con archivos CSV. Primero, debemos importar la librería y definir el nombre del archivo y las columnas que queremos incluir:
import csv
filename = "ejemplo.csv"
columns = ["nombre", "edad", "correo"]
Luego, abrimos el archivo en modo escritura y escribimos las columnas en el archivo:
with open(filename, "w") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(columns)
Ahora, podemos agregar los datos obtenidos de la página web utilizando también la función writerow
:
datos = [("Juan", 25, "[email protected]"), ("María", 30, "[email protected]")]
with open(filename, "a") as csvfile:
writer = csv.writer(csvfile)
for dato in datos:
writer.writerow(dato)
Cada vez que ejecutemos el programa, los datos serán agregados al final del archivo CSV.
Si queremos almacenar los datos en una base de datos, podemos utilizar la librería sqlite3
que viene incluida en Python. Primero, debemos importar la librería y conectarnos con la base de datos:
import sqlite3
conn = sqlite3.connect("ejemplo.db")
Luego, podemos crear una tabla en la base de datos y definir las columnas:
c = conn.cursor()
c.execute('''CREATE TABLE personas
(nombre text, edad integer, correo text)''')
Finalmente, podemos insertar los datos en la tabla:
datos = [("Juan", 25, "[email protected]"), ("María", 30, "[email protected]")]
c.executemany('INSERT INTO personas VALUES (?, ?, ?)', datos)
conn.commit()
Al trabajar con scrapping web, es importante tener en cuenta cómo vamos a almacenar los datos obtenidos. Tanto el formato CSV como las bases de datos pueden ser opciones útiles según nuestras necesidades. En el caso del CSV, Python nos ofrece la librería
csv
, mientras que para las bases de datos,sqlite3
es una alternativa práctica. Con un poco de práctica en el manejo de estas herramientas, podremos guardar y analizar datos de manera eficiente.
Implementamos un sistema de autenticación para poder acceder a sitios web protegidos
Uno de los desafíos en el scrapying web es poder acceder a sitios web protegidos por contraseña o mediante algún sistema de autenticación. Si bien nuestro scraper básico ya puede extraer los datos de sitios web públicos, nuestro objetivo es poder acceder a aquellos sitios que requieren una contraseña.
Para poder lograr esto, tuvimos que investigar un poco sobre cómo funcionan los sistemas de autenticación en la web. Descubrimos que muchos de ellos utilizan el protocolo HTTP Basic Authentication, el cual envía las credenciales de acceso al servidor mediante un encabezado de autorización en las solicitudes HTTP.
En Python, podemos enviar este encabezado utilizando la biblioteca requests
de la siguiente manera:
import requests
url = 'https://sitio-protegido.com'
username = 'nombre_de_usuario'
password = 'contraseña'
response = requests.get(url, auth=(username, password))
print(response.status_code)
Como puede verse en el código anterior, la biblioteca requests
nos permite pasar las credenciales de acceso a través del parámetro auth
en una solicitud HTTP. La biblioteca automáticamente envía un encabezado de autorización que incluye el nombre de usuario y la contraseña en formato base64.
Sin embargo, algunos sistemas de autenticación pueden ser más complejos que el protocolo HTTP Basic Authentication. Algunos sitios web utilizan formularios de inicio de sesión, tokens de autenticación o incluso CAPTCHAs para proteger su contenido.
En estos casos, nuestro scraper básico puede enfrentar un desafío mayor. Podemos superar este problema mediante la emulación de comportamientos de navegación web utilizando herramientas como Selenium
, que nos permiten automatizar el proceso de inicio de sesión, la interacción con formularios y otros comportamientos humanos en la web.
Por ejemplo, mediante Selenium
podemos acceder a un sitio web protegido con un usuario y contraseña, completar un formulario de inicio de sesión y guardar las cookies de sesión para utilizarlas en solicitudes posteriores. A continuación, se muestra un ejemplo de código que utiliza Selenium para realizar un inicio de sesión en un sitio web protegido:
from selenium import webdriver
url = 'https://sitio-protegido.com'
username = 'nombre_de_usuario'
password = 'contraseña'
driver = webdriver.Chrome()
driver.get(url)
username_field = driver.find_element_by_name('username')
username_field.send_keys(username)
password_field = driver.find_element_by_name('password')
password_field.send_keys(password)
password_field.submit()
# Guardar las cookies de sesión para utilizar en solicitudes posteriores
cookies = driver.get_cookies()
driver.quit()
Como se puede ver en el ejemplo anterior, a través de Selenium
podemos acceder a los elementos de una página web, completar un formulario de inicio de sesión y luego guardar las cookies de sesión en una variable para utilizarlas en solicitudes posteriores.
Implementar un sistema de autenticación en nuestro scraper web puede ser un desafío, pero con las herramientas adecuadas podemos emular comportamientos humanos en la web y extraer datos de sitios web protegidos. Ya sea utilizando el protocolo HTTP Basic Authentication o mediante la emulación de un comportamiento de navegador, es posible acceder a una gran cantidad de datos web que de otra manera serían inaccesibles.
Configuramos nuestro scraper para ejecutarse de manera programada
Una vez desarrollado nuestro scraper web básico en Python para la extracción de datos de sitios web, lo siguiente es configurarlo para realizar su tarea de manera programada. Esto involucra definir la frecuencia con la que se ejecutará el script y establecer la forma en que se almacenarán los datos extraídos.
Para establecer la frecuencia de ejecución, se pueden utilizar herramientas como cron en sistemas Unix o el Programador de Tareas de Windows en sistemas operativos Microsoft. En ambos casos, se puede programar la ejecución del script de acuerdo a una determinada periodicidad. Por ejemplo, se puede ejecutar el script cada hora, día, semana o mes, dependiendo de las necesidades del proyecto.
Una vez definida la periodicidad, es importante establecer la forma en que se almacenarán los datos extraídos. Para ello, se pueden utilizar distintos métodos, dependiendo de las preferencias y conocimientos del desarrollador.
Una opción es utilizar bases de datos NoSQL como MongoDB o Cassandra, que permiten almacenar grandes cantidades de datos de manera eficiente y escalable. Otra opción es guardar los datos en archivos en formato CSV o JSON, que puede resultar útil si se pretende importar la información a Excel o a otra herramienta de análisis de datos.
Para ilustrar el proceso de configuración, se presenta un ejemplo de código para ejecutar el scraper cada día a las 4:00AM y almacenar los datos extraídos en un archivo CSV:
import csv
import datetime
import time
import requests
from bs4 import BeautifulSoup
# Función para extraer datos de un sitio web
def scrape_web(url):
# Código para extraer datos utilizando BeautifulSoup
# Función para guardar los datos extraídos en un archivo CSV
def save_data_to_csv(data):
filename = f"data_{datetime.datetime.now().strftime('%Y-%m-%d')}.csv"
with open(filename, "w", newline="") as csv_file:
writer = csv.writer(csv_file)
writer.writerows(data)
# Configuración de la ejecución programada
while True:
# Verificar si es la hora programada para ejecutar el scraper
now_time = datetime.datetime.now().strftime("%H:%M")
if now_time == "04:00":
# Ejecutar el scraper y guardar los datos en un archivo CSV
data = scrape_web("https://www.ejemplo.com")
save_data_to_csv(data)
# Esperar 1 hora antes de volver a verificar la hora de ejecución programada
time.sleep(3600)
Este código configura el scraper para ejecutarse cada día a las 4:00AM y almacenar los datos extraídos en un archivo CSV cuyo nombre incluye la fecha actual. También se establece un bloqueo de espera de 1 hora antes de volver a verificar la hora de ejecución programada, para evitar sobrecargar el sitio web objetivo con solicitudes constantes.
Configurar un scraper web para ejecutarse de manera programada puede resultar muy útil para automatizar la extracción de datos y mantener actualizada la información de nuestro proyecto. Es importante establecer la periodicidad y la forma de almacenamiento adecuadas, de acuerdo a las necesidades específicas de cada caso.
Mejoramos nuestro scraper utilizando técnicas de scraping avanzadas
Después de crear nuestro primer scraper web básico en Python, es hora de dar un paso adelante y mejorar la eficiencia y precisión de nuestras extracciones de datos mediante técnicas de scraping avanzadas.
Lo primero que debemos hacer es identificar las etiquetas y atributos de HTML que contienen los datos que necesitamos. Para ello, podemos utilizar la herramienta de inspección de elementos de nuestro navegador y examinar el código fuente de la página web. Una vez localizados estos elementos, podemos utilizar librerías como BeautifulSoup o XPath para acceder a ellos de manera más específica y precisa.
Otra técnica avanzada de scraping es la utilización de proxis para el bloqueo de direcciones IP. En caso de que el sitio web que deseamos extraer información bloquee las solicitudes de nuestro scraper, podemos utilizar una lista de proxies para enviar solicitudes desde diferentes direcciones IP. Esto aumentará nuestras posibilidades de éxito y así obtendremos la información que deseamos.
Asimismo, una estrategia recomendada es la de utilizar contraseñas y sesiones al acceder a sitios web que requieren autenticación para acceder. Podemos utilizar librerías como Requests para mantenernos autenticados y tener acceso a la información de manera constante.
Otro aspecto a tener en cuenta es la optimización del tiempo de ejecución y la eficiencia de nuestro scraper. Una buena práctica es la de guardar o almacenar los datos extraídos en una base de datos en lugar de en una lista, ya que una base de datos nos permitirá realizar búsquedas y consultas más eficientes.
Para mejorar nuestro scraper en Python debemos:
- Identificar las etiquetas y atributos de HTML más específicos utilizando herramientas como BeautifulSoup o XPath.
- Utilizar un conjunto de proxies para enviar solicitudes a sitios web que bloquean solicitudes de nuestra dirección IP.
- Almacenar los datos extraídos en una base de datos en lugar de una lista para optimizar el tiempo de ejecución y la eficiencia.
Ejemplo de uso de libs para segmentar una página web
Para ilustrar el uso de BeautifulSoup para segmentar una página web en Python, se puede utilizar el siguiente código:
from bs4 import BeautifulSoup
import requests
page = requests.get("https://www.example.com")
soup = BeautifulSoup(page.content, 'html.parser')
# Buscamos el título de la página
print(soup.title)
En este ejemplo, utilizamos BeautifulSoup para acceder al contenido de la página web y buscar el elemento title
. Podríamos adaptar esto para buscar cualquier otro elemento específico.
A medida que nos familiaricemos más y más con técnicas avanzadas de web scraping en Python, podremos extraer información más detallada y precisa de cualquier sitio web que deseemos analizar.
Evitamos hacer scraping de sitios web que no nos pertenecen o de los cuales no tenemos permiso
En el desarrollo de un scraper web básico en Python, es importante tener en cuenta que existen limitaciones en cuanto a los sitios web que podemos scrappear. Es fundamental respetar los derechos de autor y propiedad intelectual de los sitios web, y evitar hacer scraping de aquellos que no nos pertenecen o de los cuales no tenemos permiso.
Además, hay ciertas normas de etiqueta en línea que debemos seguir como comunidad de developers. Algunas de las reglas de etiqueta para hacer scraper que se podrían seguir son las siguientes:
- Siempre solicitar permiso antes de scrappear cualquier sitio web.
- No scrappear información personal o confidencial.
- No sobrecargar el sitio web objetivo con solicitudes.
- Respetar el archivo robots.txt del sitio web.
Por ejemplo, imagina que quieres extraer información de una tienda en línea. Antes de empezar a hacer scraping, es importante que contactes a los dueños de la tienda para solicitar permiso. Si te lo dan, entonces podrás proceder con tu scraper.
En cuanto a la solicitud de datos personales y confidenciales, es fundamental respetar la privacidad de las personas y no extraer información que pueda comprometer su seguridad o la de la empresa de la cual se está scrappeando.
Además, es importante no sobrecargar el sitio web objetivo con solicitudes para evitar colapsarlo. Es recomendable programar una espera después de cada petición, para asegurarnos de que el servidor no se sobrecargue con las solicitudes.
Por último, el archivo robots.txt es un archivo que muchos sitios web utilizan para indicar qué páginas web y datos son públicos o privados, y cuáles no deben ser scrappeados. Es importante respetar este archivo para no violar los términos de uso del sitio web.
Respetar estas normas de etiqueta es importante para mantener una comunidad en línea efectiva y respetuosa. Además, el respeto a los derechos de autor y propiedad intelectual es fundamental para el desarrollo de tecnología de manera ética y sostenible.
Al desarrollar un scraper web básico en Python, es esencial tener en cuenta las limitaciones que existen en cuanto a los sitios web que podemos scrappear. Es fundamental respetar los derechos de autor y propiedad intelectual de los sitios web, y seguir ciertas reglas de etiqueta para evitar infringir normas y causar daños a las empresas o personas dueñas de los datos que se están extrayendo.