1. Manejo de errores en scripts
Problemas del web scraping
Imagínate: tu script está ahí, todo guapo y listo para trabajar, pero de repente resbala con una cáscara de plátano — ¡zas! Errores y fallos. ¿Cómo hacer para que sobreviva en las duras condiciones de Internet? Hoy vamos a enseñarle dos habilidades cruciales: paciencia y reintentos. Sí, sí, vamos a configurar retries y timeouts.
Trabajar con web scraping puede ser perfecto hasta que descubres que tu script de repente se detuvo debido a:
- Fallos de conexión.
- Inaccesibilidad temporal de servidores.
- Cambios impredecibles en la estructura HTML de las páginas.
Tu script, como un Jedi, debe estar preparado para lo inesperado y saber cómo manejarlo. A veces los problemas se resuelven simplemente esperando un momento y haciendo otro intento. ¡Y aquí es donde entran en escena nuestros héroes: retries y timeouts!
Introducción a los mecanismos de manejo de errores
Para empezar, recordemos lo básico: el manejo de errores en
Python. Usamos bloques try-except
para
manejar errores y asegurarnos de que no arruinen el trabajo de nuestro
script.
import requests
try:
response = requests.get('https://example.com')
response.raise_for_status() # verificar si la solicitud fue exitosa
except requests.exceptions.RequestException as e:
print(f'Ocurrió un error: {e}')
2. Configuración de retries
¿Por qué deberías usar reintentos?
Un script que simplemente se rinde ante el primer fallo es como un gato que teme a la lluvia. Pero lo que necesitas es un script que soporte un par de contratiempos. Por eso configuramos retries — para que tu script sea más confiado y valiente.
Cómo configurar reintentos
Ahora veamos cómo podemos organizar los reintentos. Una forma de hacerlo es
utilizar la librería urllib3
, que
proporciona funcionalidades para reenviar solicitudes automáticamente en caso de errores.
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
try:
response = session.get('https://example.com')
response.raise_for_status()
print(response.content)
except requests.exceptions.RequestException as e:
print(f'Ocurrió un error: {e}')
En este ejemplo, creamos una session
a la que
aplicamos el mecanismo de reintentos (Retry
).
Indicamos que se deben hacer hasta 5 intentos en caso de fallos con
códigos 500, 502, 503 y 504.
backoff_factor=1
significa que el tiempo entre
intentos aumentará de forma exponencial (1, 2, 4, 8... segundos).
3. Timeouts: evitar quedarse colgado
No más largas esperas
Los timeouts son como un despertador: evitan que te quedes esperando la respuesta del servidor. Al configurar un timeout, le dices a tu script: "¡Basta de esperar! Si el servidor no responde a tiempo, ¡sigue adelante!"
try:
response = requests.get('https://example.com', timeout=10)
response.raise_for_status()
print(response.content)
except requests.exceptions.Timeout:
print('La solicitud excedió el tiempo de espera')
except requests.exceptions.RequestException as e:
print(f'Ocurrió un error: {e}')
¿Por qué es importante?
¿Alguna vez te quedaste esperando mientras tu script intentaba obtener una respuesta de un servidor lento? Los timeouts evitan esa espera innecesaria y le permiten a tu código recuperarse rápidamente y seguir trabajando. No le hagas pensar a tu script que podría haber salido a fumar un par de veces mientras esperaba.
4. Ejemplos de configuración
Implementación de un script robusto con retries
Ahora vamos a crear un script que sea tan robusto como la armadura de Iron Man. Vamos a usar tanto timeouts como reintentos.
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
def fetch_url(url):
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
try:
response = session.get(url, timeout=10)
response.raise_for_status()
return response.content
except requests.exceptions.Timeout:
print('La solicitud excedió el tiempo de espera')
except requests.exceptions.RequestException as e:
print(f'Ocurrió un error: {e}')
return None
content = fetch_url('https://example.com')
if content:
print('¡Descargamos los datos exitosamente!')
Usando timeouts para evitar el bloqueo del script
Ya mostramos cómo configurar timeouts. Ahora asegúrate de que tu script no solo sea robusto sino que también maneje razonablemente largas esperas. En lugar de "colgarse", simplemente te recordará: "¡Oye, el servidor está pensando demasiado, no voy a esperar!"
Este enfoque sencillo y eficiente hará que tu código sea confiable y esté listo para enfrentarse a cualquier situación impredecible que pueda surgir en Internet.
Aplicación práctica
Cuando desarrollas proyectos reales de scraping, a menudo tienes que lidiar con diversas restricciones por parte de los servidores. Los retries y los timeouts son tus mejores aliados para minimizar el riesgo de fallos. Esto ayudará a garantizar que tu código funcione sin interrupciones, especialmente cuando se trata de procesamiento automatizado de datos o se requiere obtener resultados precisos de manera puntual. Estas técnicas también pueden mejorar la calidad de tu CV y la confianza de los clientes a los que les proporcionas datos.
GO TO FULL VERSION