Cómo evitar captchas al hacer scraping (sin incumplir las reglas)
La mayoría de los captchas durante el scraping son una reacción a un tráfico que parece automatizado. La forma más barata de manejarlos es dejar de dispararlos. Eso significa buscar primero una fuente de datos legítima, consultar las reglas del sitio sobre lo que puedes hacer, enviar menos peticiones y más lentas, y no descargar dos veces la misma página. Resolver un captcha es la alternativa para los casos que no puedes evitar, no el plan.
Busca primero una API o un feed oficial
Muchos sitios que reciben scraping ya ofrecen una forma de obtener los mismos datos sin captcha: una API pública, una exportación de datos, un feed RSS o sitemap, o un programa de socios. Una fuente oficial es más fiable, tiene menos probabilidades de cambiar sin aviso y le da al titular del sitio voz en cómo la usas. Busca:
- una sección para desarrolladores o de API en el pie de página,
sitemap.xmlpara la lista de páginas,- enlaces RSS o Atom en el
<head>de la página, - una página de "datos" o "descargas" para exportaciones masivas.
Si alguna de estas opciones cubre tu necesidad, úsala. Evitarás la mayoría de los captchas porque no pedirás HTML en absoluto.
Respeta robots.txt y el ritmo que indica
robots.txt te dice qué rutas permite el sitio a los clientes automatizados y, a veces, cuánto esperar entre peticiones. La biblioteca estándar de Python puede leerlo por ti:
import time
from urllib.robotparser import RobotFileParser
import requests
USER_AGENT = "ExampleBot/1.0 (+https://example.com/bot)"
parser = RobotFileParser()
parser.set_url("https://example.com/robots.txt")
parser.read()
delay = parser.crawl_delay(USER_AGENT) or 5 # alternativa conservadora de 5 segundos
urls = [
"https://example.com/products?page=1",
"https://example.com/products?page=2",
]
last_request = 0.0
for url in urls:
if not parser.can_fetch(USER_AGENT, url):
print("skipped by robots.txt:", url)
continue
wait = delay - (time.monotonic() - last_request)
if wait > 0:
time.sleep(wait)
resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=30)
last_request = time.monotonic()
print(url, resp.status_code)
Si robots.txt prohíbe una ruta, la respuesta honesta es dejarla en paz o pedir permiso al titular. Rodearla con un navegador no cambia lo que el sitio pidió.
Ve más despacio y reparte las peticiones
Un ritmo constante y moderado rara vez dispara un desafío, mientras que una ráfaga casi siempre lo hace. Algunos hábitos marcan una gran diferencia:
- Elige un ritmo de peticiones por sitio y mantenlo, en lugar de ir a máxima velocidad.
- Añade una variación aleatoria (jitter) para que el tiempo no sea perfectamente regular.
- Detente y espera un rato cuando veas un 429 o una página de captcha.
- Ejecuta los trabajos en horas de poca carga si la carga del sitio te preocupa.
Usa caché y no vuelvas a descargar
Cada petición que no haces es una petición que el sitio no tiene que atender. Guarda las páginas que descargas con su fecha y un hash del contenido, y solo vuelve a pedirlas cuando sea probable que el contenido haya cambiado. Las peticiones condicionales con las cabeceras If-Modified-Since o ETag permiten que el servidor responda "no modificado" de forma barata cuando las soporta.
Reutiliza sesiones y envía cabeceras normales
Una sesión que guarda cookies entre peticiones se comporta más como un visitante que como un script que empieza de cero cada vez. Usa requests.Session() para cada sitio y envía un User-Agent claro y honesto que identifique a tu bot y un contacto. No te hagas pasar por un navegador para saltarte una regla. Si un sitio necesita JavaScript para mostrar su contenido, usa una herramienta de navegador para esas páginas y mantén los mismos límites de ritmo.
Cuando aun así aparece un captcha
Algunos sitios mostrarán un captcha pase lo que pase si te comportas con cuidado. Detéctalo en el código y detén ese trabajo en lugar de machacar la página. La detección y la resolución opcional de PopularCaptcha se explican en captchas en el web scraping.
Planifica el rastreo antes de empezar
Un rastreo que descarga todo cada día es la forma más fácil de disparar un captcha. Planifica el trabajo primero:
- Prioriza. Decide qué páginas cambian a menudo y cuáles rara vez. Rastrea las frecuentes con frecuencia y el resto con poca frecuencia.
- Usa las fechas del sitemap. Muchos sitemaps incluyen un valor
lastmod. Omite las URL que no han cambiado desde tu última visita. - Rastrea de forma incremental. Guarda la última descarga correcta de cada URL y continúa desde ahí, en lugar de volver a empezar desde la primera página tras un fallo.
- Reparte la carga. Divide una lista grande en lotes y ejecútalos a lo largo del día, no todos a la vez.
Un plan así reduce el número de peticiones, que es la palanca más importante que tienes.
Escribe el plan como un pequeño archivo de configuración o una tabla: los sitios, las secciones, el intervalo de actualización y el presupuesto diario de peticiones para cada uno. Cuando se agote el presupuesto, el trabajo se detiene hasta la siguiente ventana. Tratar el presupuesto como un límite estricto, y no como una recomendación, es lo que evita que un rastreador derive hacia el patrón de tráfico que dispara captchas. Revisa el presupuesto cada pocas semanas, porque un sitio que crece también puede crecer en tráfico, y lo que era razonable el trimestre pasado puede no serlo ahora.
Scrapea de forma responsable
- Revisa
robots.txty los términos de servicio antes de empezar, y respeta lo que dicen. - Mantén bajo el ritmo de peticiones y detente cuando el sitio dé señales de que está sufriendo.
- No recopiles datos personales que no tienes motivo para conservar, y bórralos cuando ya no los necesites.
- No republiques contenido protegido por derechos de autor en masa. Usa los datos para análisis, comparación o tu propio producto, y cita la fuente cuando corresponda.
- Contacta con el titular del sitio si necesitas un volumen mayor. Puede ofrecerte un feed.