BeautifulSoup y requests a través de proxies móviles: guía paso a paso para principiantes
Contenido: Introducción · Preparación previa · Conceptos básicos · Paso 1: Instalación de Python y bibliotecas · Paso 2: Prueba rápida sin proxy · Paso 3: Solicitud a través de un proxy móvil · Paso 4: Rotación de IP · Paso 5: Errores, timeouts y repeticiones · Paso 6: Manejo de CAPTCHA · Verificación de resultados · Errores comunes · Funcionalidades adicionales · FAQ · Conclusión
Introducción
En esta guía paso a paso, configurarás un entorno de trabajo en Python, realizarás solicitudes a páginas web a través de proxies móviles, analizarás los datos necesarios utilizando BeautifulSoup y aprenderás a trabajar de manera segura y estable con la rotación de IP. Usaremos la biblioteca requests para las solicitudes de red y BeautifulSoup para analizar HTML. Al final, tendrás un parser mínimo viable que: envía solicitudes HTTP a través de un proxy móvil, reemplaza correctamente los encabezados para dispositivos móviles, repite solicitudes con un backoff inteligente ante errores, rota IP en el proveedor de proxies móviles, maneja el CAPTCHA de manera adecuada y guarda los datos de forma conveniente.
¿Para quién es esta guía? Para aquellos que son principiantes en web scraping; para especialistas en áreas afines (marketing, investigación, OSINT) que necesitan una herramienta simple y confiable; para desarrolladores que deseen crear rápidamente un prototipo funcional y continuar su desarrollo.
¿Qué necesitas saber de antemano? Habilidades básicas en el uso de computadoras; entendimiento de qué es un archivo, una carpeta y cómo ejecutar la línea de comandos; tener un conocimiento mínimo de Python será un plus, pero no es obligatorio, ya que avanzamos paso a paso. Importante: debes contar con una base legal para procesar las páginas objetivo y cumplir con las normas de los sitios, incluyendo robots.txt y acuerdos de usuario.
¿Cuánto tiempo tomará? 2-4 horas si sigues los pasos de manera secuencial. La instalación del entorno y la prueba rápida tomarán hasta 30 minutos. La conexión con el proxy móvil y la configuración de la rotación tardarán entre 40 minutos y 1.5 horas. La adición de manejo de errores y CAPTCHA tomará de 30 a 60 minutos.
Consejo: Guarda el enlace a la sección Paso 4: Rotación de IP y Paso 5: Errores, timeouts y repeticiones. Estos bloques son los que más se utilizan para depurar y mejorar la estabilidad.
⚠️ Atención: Todo el material se proporciona con fines educativos y de práctica para el scraping legal. No utilices técnicas para eludir restricciones de acceso, no violes la legislación y los términos de uso de los sitios. Además, no discutimos el uso de VPN o otras formas de eludir bloqueos.
Preparación previa
Herramientas y accesos necesarios: computadora con Windows, macOS o Linux; acceso a Internet; Python 3.11-3.13 instalado (se recomienda la versión más actual); instalador de paquetes pip; editor de texto (Visual Studio Code, PyCharm Community o cualquier otro). También necesitarás una cuenta con un proveedor de proxies móviles. Como ejemplo, puedes basarte en los requisitos funcionales que ofrecen los servicios de mobileproxy.space: endpoint proxy individual, autorización por usuario y contraseña o por IP, rotación configurada (por temporizador o por API), estadísticas de solicitudes.
Requisitos del sistema: al menos 4 GB de RAM; 1-2 GB de espacio en disco para Python y bibliotecas; un canal de Internet estable de al menos 10 Mbps; posibilidad de instalar programas. Los derechos de administrador son necesarios solo para instalar Python (en Windows).
Qué descargar e instalar: instalador de Python; editor de código (por ejemplo, VS Code); bibliotecas requests, beautifulsoup4, lxml (para un parsing de HTML más rápido).
Creando copias de seguridad (si es relevante): antes de modificar proyectos existentes, haz una copia de la carpeta con el código. Si es la primera vez que creas un proyecto, establece un directorio de trabajo separado. Guarda el archivo con las credenciales del proxy fuera del repositorio y, si es posible, usa un archivo .env y un gestor de secretos.
Consejo: Crea una carpeta de proyecto sin espacios y sin caracteres cirílicos en el nombre, por ejemplo, parser_mobile_proxy. Esto facilitará la ejecución de scripts y evitará errores de ruta.
Conceptos básicos
Terminología clave en lenguaje sencillo: el parsing o web scraping es la recolección automática de datos públicamente disponibles de las páginas de un sitio. requests es una biblioteca de Python para realizar solicitudes HTTP. BeautifulSoup es una biblioteca de Python para analizar HTML y extraer fragmentos de contenido según etiquetas, clases y atributos. Un proxy es un servidor intermedio que envía solicitudes al sitio en su nombre. Un proxy móvil es aquel que utiliza direcciones IP de operadores móviles. La rotación de IP es el cambio de dirección IP de salida en un período especificado o por comando.
Principios básicos de operación: formas un запрос HTTP al sitio; tu solicitud pasa a través de un proxy móvil; el sitio ve la dirección del proxy y no la tuya. Obtienes la página HTML y la analizas con BeautifulSoup.
Lo que es importante entender antes de comenzar: respeta el robots.txt y las condiciones del sitio; no sobrecargues el servidor con solicitudes frecuentes; utiliza timeouts; envía una cantidad razonable de solicitudes paralelas; maneja códigos de respuesta 4xx y 5xx. Un proxy móvil ayuda a reducir la probabilidad de activadores de fraude y restricciones, ya que los rangos de IP móviles son utilizados activamente por usuarios reales. Mientras tanto, la estabilidad depende de la calidad del proveedor, la carga y la corrección de tu código.
⚠️ Atención: No uses parsing para eludir autorización o acceder a secciones cerradas sin permiso. No intentes interferir en el funcionamiento del sitio. Trabaja solo con datos abiertos, para los cuales posees derecho a procesamiento.
Paso 1: Instalación de Python y bibliotecas
Objetivo del paso
Instalar Python y las bibliotecas necesarias, crear el proyecto y los archivos básicos. Después de este paso, podrás ejecutar scripts y realizar solicitudes HTTP.
Instrucciones paso a paso
- Descarga e instala Python desde el sitio oficial. Al instalar en Windows, marca la opción Add Python to PATH. En macOS, puedes usar el gestor de paquetes brew o el instalador oficial. En Linux, utiliza los repositorios de tu sistema.
- Verifica la instalación. Abre la terminal y ejecuta el comando: python --version o python3 --version. Asegúrate de que la versión sea de 3.11 a 3.13.
- Crea una carpeta de proyecto, como C:\Users\tu_usuario\parser_mobile_proxy o /Users/tu_usuario/parser_mobile_proxy.
- Abre la carpeta del proyecto en el editor de código. Crea el archivo main.py y el archivo requirements.txt.
- Agrega a requirements.txt: requests==2.32.3; beautifulsoup4==4.12.3; lxml==5.2.2.
- Instala las dependencias con el comando pip install -r requirements.txt o pip3 install -r requirements.txt.
- Verifica que las bibliotecas estén instaladas. En la terminal, ejecuta python -c "import requests, bs4, lxml; print('ok')". Debería mostrar ok.
Puntos importantes
Importante: Instala las bibliotecas en un entorno virtual para que las versiones no entren en conflicto. Puedes crear un entorno con el comando python -m venv .venv y activarlo con source .venv/bin/activate (macOS, Linux) o .venv\Scripts\activate (Windows), después de lo cual podrás ejecutar pip install -r requirements.txt.
Consejo: Si no tienes derechos de administrador, utiliza la instalación de usuario pip install --user -r requirements.txt o trabaja en un entorno virtual.
Resultado esperado
Puedes ejecutar un script simple e importar los módulos necesarios sin errores.
Problemas posibles y soluciones
- El comando python no se encuentra. Solución: utiliza python3 o asegúrate de que PATH esté configurado. Reinstala Python con la opción Add to PATH.
- Conflicto de versiones con lxml. Solución: actualiza pip (python -m pip install --upgrade pip), luego reinstala lxml.
- Faltan permisos para la instalación. Solución: activa el entorno virtual o utiliza el flag --user.
✅ Verificación: El comando python -c "import requests, bs4; print('ready')" imprime ready, y el archivo main.py existe en la carpeta del proyecto.
Paso 2: Prueba rápida de parsing sin proxy
Objetivo del paso
Comprobar que la combinación básica requests + BeautifulSoup funciona antes de conectar los proxies. Realizaremos una solicitud a una página de prueba y extraeremos el título.
Instrucciones paso a paso
- Abre el archivo main.py en el editor.
- Inserta el código básico para la solicitud y el parsing.
- Ejecuta el script y verifica la salida.
Código de ejemplo
import requests; from bs4 import BeautifulSoup; session = requests.Session(); session.headers.update({"User-Agent": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0 Mobile Safari/537.36"}); url = "https://example.com"; resp = session.get(url, timeout=30); html = resp.text; soup = BeautifulSoup(html, "lxml"); title = soup.title.text.strip() if soup.title else "(sin etiqueta title)"; print("Estado:", resp.status_code, "Título:", title)Puntos importantes
Importante: Usamos un User-Agent móvil para simular un navegador móvil. Esto ayudará a alinear el comportamiento con el proxy móvil en el siguiente paso.
Consejo: Si la página objetivo puede devolver una versión diferente para escritorio y móviles, guarda el HTML en un archivo para depuración: open("page.html", "w", encoding="utf-8").write(html). Así podrás estudiar la estructura de las etiquetas.
Resultado esperado
El script imprime el código de respuesta y el título de la página. Esta es una verificación básica de que el parser puede ver HTML y desglosarlo.
Problemas posibles y soluciones
- Código 403 o 404. Solución: verifica la URL; intenta cambiar el User-Agent; asegúrate de que el sitio esté disponible.
- Timeout. Solución: aumenta el timeout a 60, verifica la conexión a Internet.
- Código de codificación incorrecto. Solución: usa resp.encoding = resp.apparent_encoding antes del parsing.
✅ Verificación: Ves el estado 200 y la línea Título: (nombre de la página). En la carpeta puede aparecer page.html si guardaste el HTML.
Paso 3: Solicitud a través de un proxy móvil
Objetivo del paso
Conectar un proxy móvil a requests, enviar la solicitud y asegurarte de que el tráfico realmente pase a través del proxy y no directamente. También agregaremos autorización y revisaremos los encabezados.
Qué preparar
Los datos de tu proxy móvil: host (por ejemplo, proxy.provider.local o dirección IP), puerto (por ejemplo, 12345), usuario y contraseña para la autorización, o una lista blanca de IP confirmada si el proveedor autoriza por dirección IP. La mayoría de los proveedores móviles, incluyendo soluciones de mobileproxy.space, proporcionan estos parámetros en el área de cliente.
Instrucciones paso a paso
- Abre el archivo main.py.
- Agrega un diccionario proxies con los datos de tu proxy.
- Envía la solicitud a través de session.get con el parámetro proxies.
- Verifica que la respuesta llegó y analiza la página.
Código de ejemplo
import requests; from bs4 import BeautifulSoup; PROXY_HOST = "PROXY_HOST"; PROXY_PORT = 12345; PROXY_USER = "USER"; PROXY_PASS = "PASS"; proxy_auth = f"http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"; proxies = {"http": proxy_auth, "https": proxy_auth}; session = requests.Session(); session.headers.update({"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Mobile/15E148 Safari/604.1", "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7"}); url = "https://example.com"; resp = session.get(url, proxies=proxies, timeout=45); print("HTTP:", resp.status_code); soup = BeautifulSoup(resp.text, "lxml"); print("TÍTULO:", soup.title.text.strip() if soup.title else "(sin)")Puntos importantes
Importante: Si tu proveedor autoriza por IP, usa el formato proxies sin usuario y contraseña: "http": f"http://{PROXY_HOST}:{PROXY_PORT}". Asegúrate de que tu IP actual esté en la lista blanca en el panel del proveedor.
Consejo: En la primera ejecución, agrega el parámetro verify=False solo para diagnóstico de errores TLS. No lo dejes en producción. Es mejor instalar certificados raíz si el proveedor lo requiere.
Consejo: Guarda la configuración del proxy en un archivo .env: PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS. Cárgalos a través de os.getenv o la biblioteca python-dotenv para no guardar secretos en el código.
Resultado esperado
Obtienes un código 200 y un TÍTULO correcto. Si en la página objetivo se muestra la IP, será diferente de la tuya, porque la solicitud va a través del proxy móvil.
Problemas posibles y soluciones
- 407 Proxy Authentication Required. Solución: verifica el usuario y la contraseña; asegúrate de que estás usando el formato de URL correcto con autorización.
- 403 Forbidden. Solución: cambia el User-Agent por uno móvil; verifica los encabezados Accept-Language; reduce la frecuencia de solicitudes.
- ConnectionError o ReadTimeout. Solución: aumenta el timeout, verifica la estabilidad del proxy con el proveedor, repite la solicitud con backoff.
✅ Verificación: La respuesta llega con estado 200. El TÍTULO es correcto. Si pruebas en una página que muestra tu IP, esta corresponderá a la IP del proxy móvil (checa el dashboard del proveedor).
Paso 4: Rotación de direcciones IP de manera segura y predecible
Objetivo del paso
Configurar el cambio de IP del proxy móvil por temporizador o a través de un comando API. Esto aumenta la resiliencia del scraping y reduce las posibilidades de caer en restricciones de seguridad. Implementaremos dos métodos: lista cíclica de endpoints de proxy y rotación dentro de un mismo endpoint por API o temporizador del proveedor.
Instrucciones paso a paso
- Define la estrategia de rotación: por tiempo (por ejemplo, cada 5-10 minutos), por número de solicitudes (por ejemplo, cada 10-20 solicitudes) o híbrido.
- Si tienes varios endpoints de proxy, prepárate una lista y realiza un cambio round-robin.
- Si el proveedor tiene una API de cambio de IP para un solo endpoint, agrega la llamada en el código y espera una ventana de rotación confirmada (normalmente entre 10-60 segundos).
- Ten en cuenta las limitaciones del proveedor: tiempo mínimo de rotación y límite de llamadas a la API por día.
- Incluye pausas y verifica la IP después de la rotación para asegurarte de que una nueva IP esté activa.
Ejemplo de round-robin entre múltiples endpoints
import itertools, requests; from bs4 import BeautifulSoup; proxies_list = [ {"http": "http://user1:pass1@host1:10001", "https": "http://user1:pass1@host1:10001"}, {"http": "http://user2:pass2@host2:10002", "https": "http://user2:pass2@host2:10002"} ]; cycle = itertools.cycle(proxies_list); def fetch(url): s = requests.Session(); s.headers.update({"User-Agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Mobile Safari/537.36"}); proxies = next(cycle); r = s.get(url, proxies=proxies, timeout=45); return r; r = fetch("https://example.com/catalog"); print(r.status_code)Ejemplo de rotación dentro de un único endpoint mediante API
Muchos proveedores de proxies móviles, incluidos los de clase mobileproxy.space, permiten cambiar la IP en un mismo endpoint por temporizador (por ejemplo, cada N minutos) o por solicitud a la API. En el código, esto se manifiesta como una solicitud adicional a la URL de servicio del proveedor. A continuación, un esquema general. Reemplaza la URL y el token por los tuyos del panel del proveedor. Ten en cuenta los límites y ventanas de rotación.
import time, requests; def rotate_ip(api_rotate_url, timeout=30): try: r = requests.get(api_rotate_url, timeout=timeout); return r.status_code, r.text; except Exception as e: return None, str(e); api_url = "http://PROXY_HOST:PORT/changeip?token=YOUR_TOKEN"; status, body = rotate_ip(api_url); print("ROTATE:", status, body); time.sleep(20); # espera la ventana de rotación; s = requests.Session(); proxies = {"http": "http://USER:PASS@PROXY_HOST:PORT", "https": "http://USER:PASS@PROXY_HOST:PORT"}; resp = s.get("https://example.com", proxies=proxies, timeout=45); print(resp.status_code)Puntos importantes
Importante: La rotación no es una solución mágica. Si realizas demasiadas solicitudes en poco tiempo, se pueden activar los disparadores de seguridad incluso con el cambio de IP. Mantén una frecuencia moderada, utiliza retrasos aleatorios y repeticiones con backoff.
Consejo: Planifica la rotación por hora y carga. Por ejemplo, una rotación cada 10-20 minutos más un cambio después de 15-25 solicitudes a un dominio. Esto suaviza el comportamiento y lo hace parecer natural.
Consejo: Guarda metadata de la solicitud: qué proxy se utilizó, qué IP se tenía, qué estado devolvió el servidor. Esto facilitará la depuración.
Resultado esperado
Tu código cambia de manera estable entre endpoints de proxy o inicia el cambio de IP en un solo endpoint y espera la ventana de rotación. Después del cambio, las solicitudes siguen siendo exitosas con estado 200.
Problemas posibles y soluciones
- IP no cambia después de llamar a la API. Solución: espera más tiempo, verifica los límites; asegúrate de que estás llamando a la URL correcta y que el token es válido; revisa la estadística en el panel del proveedor.
- Disponibilidad cae en el momento de la rotación. Solución: durante el período de rotación, cambia a otro endpoint, usa un canal de respaldo en round-robin.
- Frecuentes 429 Too Many Requests. Solución: aumenta el intervalo entre solicitudes, reduce el número total de hilos simultáneos.
✅ Verificación: Si imprimes regularmente la IP actual en los registros, verás que la dirección cambia de acuerdo con la estrategia de rotación, y el estado de las solicitudes se mantiene entre 200 y 299.
Paso 5: Manejo de errores, timeouts y repeticiones
Objetivo del paso
Hacer que tu parser sea resistente a fallos de red y errores temporales del servidor. Agregaremos timeouts, repeticiones con backoff exponencial, retrasos aleatorios y registro de logs.
Instrucciones paso a paso
- Define el número máximo de repeticiones (por ejemplo, 3-5) y el retraso básico (por ejemplo, 1-2 segundos).
- Implementa backoff: en cada fallo, aumenta la espera por el doble más un poco de ruido aleatorio.
- Captura los códigos 5xx y 429 como temporales, y considera cuidadosamente los 4xx (403 suele ser un bloqueo permanente).
- Agrega logs claros para entender lo que está sucediendo en cada paso.
- Encapsula la llamada de red en una función fetch_safely que sea fácil de reutilizar.
Código de ejemplo
import time, random, requests; from bs4 import BeautifulSoup; def fetch_safely(url, session, proxies=None, max_retries=4, base_delay=1.5, timeout=45): attempt = 0; while attempt <= max_retries: try: r = session.get(url, proxies=proxies, timeout=timeout); if r.status_code in (200, 201): return r; elif r.status_code in (429, 500, 502, 503, 504): delay = base_delay * (2 ** attempt) + random.uniform(0.0, 0.7); time.sleep(delay); attempt += 1; continue; elif r.status_code == 403: return r; else: return r; except (requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError) as e: delay = base_delay * (2 ** attempt) + random.uniform(0.1, 0.9); time.sleep(delay); attempt += 1; continue; return NonePuntos importantes
Importante: Establece timeouts razonables: 30-60 segundos para canales inestables, 10-20 segundos para redes rápidas. No desactives la verificación SSL a menos que sea absolutamente necesario.
Consejo: Para los logs, utiliza el módulo logging. Al iniciar, agrega una configuración mínima: logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s"). Esto es útil para diagnóstico.
Consejo: Separa "fallos temporales" y "fallos permanentes". Temporales, reintenta; permanentes, registra y sigue adelante para evitar ciclos.
Resultado esperado
El script continúa ejecutándose ante errores temporales y devuelve una respuesta, o avanza correctamente a la siguiente tarea sin fallar.
Problemas posibles y soluciones
- Las repeticiones no ayudan, siempre 429. Solución: disminuye la frecuencia de solicitudes, alarga los retrasos, incrementa la ventana entre rotaciones de IP.
- 403 permanentes. Solución: revisa la política del sitio, verifica la corrección de los encabezados, reduce la frecuencia, usa API oficiales si es necesario.
- Frecuentes ConnectionError. Solución: verifica el proveedor de proxies móviles; puede que necesites otro región o puerto.
✅ Verificación: Al simular fallos, verás en los registros las repeticiones con retrasos crecientes. Después de 1-2 intentos, muchas solicitudes finalizan con éxito.
Paso 6: Detección y manejo de captchas de manera legal
Objetivo del paso
Aprender a reconocer cuándo la página ha devuelto un captcha y reaccionar adecuadamente: reduciendo la carga, pausando temporalmente las solicitudes y utilizando correctamente la rotación de IP. No eludimos la protección, actuamos dentro del marco del scraping ético.
Instrucciones paso a paso
- Define las señales de CAPTCHA en los sitios objetivo: presencia de palabras clave en el HTML (captcha, g-recaptcha), formularios con campos inusuales, páginas de soporte.
- Agrega un código que verifique el contenido HTML antes de ejecutar la lógica principal de parsing.
- Si se detecta un CAPTCHA, ejecuta acciones suaves: aumenta la pausa; reduce la frecuencia en el dominio; inicia la rotación de IP; intenta realizar la solicitud nuevamente.
- Si el CAPTCHA persiste, detén los intentos automáticos y estudia los términos de uso del sitio. Puede que los datos estén disponibles a través de una API oficial.
Código de ejemplo
from bs4 import BeautifulSoup; import time, requests; def is_captcha(html): text = html.lower(); hints = ["captcha", "g-recaptcha", "hcaptcha", "distil", "cloudflare", "please verify", "are you a human"]; return any(h in text for h in hints); def get_with_captcha_handling(url, session, proxies, rotate_func=None): r = session.get(url, proxies=proxies, timeout=45); if r.status_code == 200 and not is_captcha(r.text): return r; time.sleep(10); if rotate_func: try: rotate_func(); time.sleep(20); except Exception: pass; r2 = session.get(url, proxies=proxies, timeout=60); return r2Puntos importantes
Importante: Si el captcha sigue apareciendo, disminuye la intensidad del scraping, espera la próxima ventana de rotación o cambia a otro endpoint. Mantén la ética y sigue las reglas del sitio.
Consejo: A veces, el captcha se muestra solo en ciertos caminos. Disminuye la frecuencia solo para esos caminos, no para todo el dominio. Esto mantendrá la velocidad general.
⚠️ Atención: No discutimos el uso de servicios de terceros para eludir captchas, scripts de elusión, emulación de navegadores ni técnicas similares. Trabaja solo dentro de los marcos permitidos, utilizando API oficiales si están disponibles.
Resultado esperado
El script puede responder suavemente a la aparición de un captcha: hace una pausa, inicia el cambio de IP (si está disponible) y repite la solicitud. Esto reduce la cantidad de rechazos erróneos y ayuda a mantener la estabilidad.
Problemas posibles y soluciones
- Captchas en cada solicitud. Solución: disminuye drásticamente la frecuencia, utiliza intervalos variados entre solicitudes, cambia la zona horaria o la región del proxy con el proveedor (si está disponible), examina robots.txt.
- El captcha desaparece, pero los datos son inestables. Solución: aumenta el timeout, guarda y analiza el HTML, compara versiones de páginas para diferentes IP.
✅ Verificación: Al activar el trigger de forma artificial (por ejemplo, solicitudes frecuentes en poco tiempo), verás pausas y rotaciones en los registros, y después de eso, respuestas exitosas sin captcha.
Verificación de resultado
Checklist
- Python instalado, dependencias instaladas.
- El script sin proxy obtiene HTML y parsea el título.
- El script con proxy móvil devuelve estado 200.
- La rotación de IP está activada y verificada.
- Las repeticiones ante errores funcionan, los timeouts están configurados.
- Hay manejo de señales de captcha.
- Los datos se guardan en un archivo o se imprimen en consola como se espera.
Cómo probar
- Ejecuta la solicitud básica sin proxy y verifica que el parsing del título funcione.
- Activa el proxy y repite la solicitud, compara resultados.
- Inicia el cambio de IP con el proveedor (si está disponible) y repite la solicitud después de 20-60 segundos.
- Reduce artificialmente el timeout a 1-2 segundos y verifica que las repeticiones con backoff se activen y luego regresen a la normalidad al recuperar el timeout.
- Carga el sitio con varias solicitudes seguidas y asegúrate de que al aparecer señales de captcha se establezcan pausas y, si es necesario, se active la rotación.
Métricas de éxito
- La tasa de solicitudes exitosas es superior al 90% en sitios "tranquilos".
- Los códigos 429 y 5xx ocurren raramente y son manejados con repeticiones.
- La rotación de IP ocurre según lo programado, sin largos períodos de inactividad.
Consejo: Introduce métricas de "tiempo de respuesta" y "número de repeticiones" y regístralas. Esto ayudará a determinar cuándo cambiar la estrategia de rotación o la frecuencia de las solicitudes.
Errores comunes y soluciones
- Problema: 407 Proxy Authentication Required. Causa: usuario o contraseña incorrecta, URL de proxy mal formada. Solución: comprueba el formato http://USER:PASS@HOST:PORT, asegúrate de que no hay caracteres o espacios adicionales; si la autorización es por IP, elimina el usuario y la contraseña.
- Problema: 403 Forbidden. Causa: se activó la protección del sitio, User-Agent inadecuado o solicitudes muy frecuentes. Solución: utiliza un User-Agent móvil, reduce la frecuencia, activa la rotación de IP, verifica Accept, Accept-Language y Referer.
- Problema: 429 Too Many Requests. Causa: límite de frecuencia superado. Solución: añade un backoff exponencial, incrementa los pausas, realiza rotaciones con menos frecuencia, distribuye las solicitudes durante el día.
- Problema: ConnectionError o ReadTimeout. Causa: canal de proxy inestable o red saturada. Solución: aumenta el timeout, repite con backoff, utiliza un endpoint de respaldo.
- Problema: parsing incorrecto, datos vacíos. Causa: ha cambiado la estructura HTML o se cargan contenidos a través de JavaScript. Solución: actualiza los selectores de BeautifulSoup; si los datos se generan dinámicamente, examina las solicitudes de red de la página y usa sus endpoints de JSON oficiales si están disponibles y es legal hacerlo.
- Problema: captcha en cada página. Causa: carga agresiva o actividad sospechosa. Solución: reduce la frecuencia, aumenta las pausas, utiliza rotación, verifica la corrección de los encabezados y el cumplimiento de robots.txt.
- Problema: bloqueo después de varias solicitudes exitosas. Causa: comportamiento predecible del script. Solución: introduce retrasos aleatorios, varía el orden de las solicitudes, alterna proxies, actualiza los encabezados.
Consejo: Guarda ejemplos de HTML antes y después de incidentes. Esto ayudará a diferenciar rápidamente entre un cambio en la estructura y signos de protección anti-bots.
Funcionalidades adicionales
Configuraciones avanzadas
- Sesiones y cookies: utiliza requests.Session para almacenar automáticamente cookies, esto hace que el comportamiento se asemeje más al de un navegador real.
- Encabezados: añade Accept, Accept-Language, Referer y DNT según sea necesario. Cambia el User-Agent de un grupo de agentes móviles.
- Proxies SOCKS: si es necesario, conecta requests[socks]. Sin embargo, los proxies móviles suelen proporcionarse como HTTP(S).
- Guardar en CSV o JSON: después del parsing, guarda los datos en archivos. Esto es conveniente para integraciones.
Ejemplo de mini-pipeline de parsing
import csv, requests, time; from bs4 import BeautifulSoup; MOBILE_UA = "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Mobile Safari/537.36"; session = requests.Session(); session.headers.update({"User-Agent": MOBILE_UA}); proxies = {"http": "http://USER:PASS@HOST:PORT", "https": "http://USER:PASS@HOST:PORT"}; urls = ["https://example.com/page1", "https://example.com/page2"]; rows = []; for u in urls: r = session.get(u, proxies=proxies, timeout=45); if r.status_code == 200: s = BeautifulSoup(r.text, "lxml"); title = s.title.text.strip() if s.title else ""; rows.append({"url": u, "title": title}); time.sleep(2); open("data.csv", "w", newline="", encoding="utf-8"); with open("data.csv", "w", newline="", encoding="utf-8") as f: w = csv.DictWriter(f, fieldnames=["url","title"]); w.writeheader(); w.writerows(rows); print("guardado:", len(rows))Optimización
- Procesamiento por lotes: agrupa solicitudes por dominios considerando retrasos y rotación.
- Caché: guarda las páginas ya obtenidas localmente para no volver a solicitarlas sin necesidad.
- Estrategia de duración: planea los tiempos de las solicitudes en horas "no pico", cuando el sitio esté menos cargado.
Consejo: Si tienes muchas tareas, divídelas en pequeños lotes y ejecútalas secuencialmente. Esto mejora la estabilidad y disminuye la probabilidad de captchas.
Consejo: Muchos proveedores de proxies móviles (incluyendo soluciones de mobileproxy.space) tienen un panel de control con estadísticas claras. Cruza tiempos, frecuencia y códigos de respuesta; esto te dará una idea de cuándo es más correcto rotar.
FAQ
Pregunta: ¿Cómo saber si la solicitud está pasando de verdad por un proxy móvil? Respuesta: Verifica en el panel del proveedor las conexiones activas y la IP externa actual, compárala con la que ves en las respuestas de la página. Además, el proveedor suele mostrar estadísticas de las solicitudes al endpoint.
Pregunta: ¿Cómo elegir el User-Agent: Android o iOS? Respuesta: Escoge la plataforma para la que trabaja tu contenido (versión móvil del sitio). A menudo, el agente de Android proporciona un resultado predecible. Prueba ambos y registra dónde hay menos rechazos.
Pregunta: ¿Con qué frecuencia cambiar IP al raspar? Respuesta: La recomendación básica es no hacerlo más de una vez cada 10-20 minutos o después de 15-25 solicitudes en un dominio. Ajusta según la carga, no abuses de la rotación frecuente.
Pregunta: ¿Qué hacer si el sitio entrega contenido a través de JavaScript? Respuesta: Examina las solicitudes de red de la página (en las herramientas para desarrolladores del navegador). A menudo, los datos llegan a través de endpoints de JSON. Si el acceso es legal y no vulnera condiciones, usa esos endpoints. Si no, verifica las reglas del sitio.
Pregunta: ¿Se pueden usar varios proveedores móviles a la vez? Respuesta: Sí, si es necesario para repartir la carga. Configura un round-robin y asegúrate de los límites de cada proveedor.
Pregunta: ¿Cómo almacenar las credenciales de forma segura? Respuesta: Usa variables de entorno y un archivo .env, no cometas secretos en el repositorio. En producción, almacena secretos en gestores de secretos.
Pregunta: ¿Cómo detener correctamente el script en caso de errores masivos? Respuesta: Implementa un contador de intentos fallidos y un límite superior. Si N solicitudes a diferentes dominios fallan seguidas, haz una pausa prolongada, registra el incidente y termina el proceso.
Pregunta: ¿Necesito lxml si hay un parser integrado como html.parser? Respuesta: El parser integrado es adecuado para casos simples. lxml es más rápido y robusto ante HTML parcialmente incorrecto. Para el scraping regular, se recomienda lxml.
Pregunta: ¿Qué hacer si el sitio cambia la estructura? Respuesta: Guarda páginas de prueba, añade verificaciones de regresión sobre los selectores. Cuando se produzcan cambios, actualiza la lógica de BeautifulSoup y escribe funciones adaptadoras para la nueva estructura.
Pregunta: ¿Por qué necesito un proxy móvil si el habitual funciona también? Respuesta: Las direcciones móviles suelen levantar menos sospechas debido a las particularidades de las redes móviles y la distribución del tráfico. Esto aumenta la probabilidad de respuestas estables a una carga razonable.
Conclusión
Resumen de lo realizado: has instalado Python y las bibliotecas requests y BeautifulSoup, comprobaste el parsing básico sin proxies, añadiste un proxy móvil y verificaste que las solicitudes pasan a través de él, configuraste rotación de IP de varias maneras, implementaste manejo de errores y una reacción suave ante El CAPTCHA. Ahora cuentas con un proyecto base para un scraping sostenible y ético de datos públicos.
¿Qué hacer a continuación? Desarrolla el parser según tus objetivos: añade nuevos selectores, guarda los datos en una base, establece horarios de ejecución. Incluye alertas cuando la tasa de solicitudes exitosas caiga o cuando aumenten los estados 429 y 403. Agrega un archivo de configuración para parámetros de control (frecuencia, rotación, timeouts).
¿En qué profundizar? Estudia solicitudes asíncronas en Python (aiohttp), colas de tareas (Celery, RQ), almacenamiento y análisis de datos (SQLite, PostgreSQL, Pandas). Analiza la legalidad del procesamiento de datos e interacción con sitios, así como el acceso oficial a los datos a través de APIs legales. Para proxies móviles, utiliza funciones similares a las que ofrecen los modernos servicios de mobileproxy.space: rotación flexible, estadísticas, diferentes regiones y soporte estable.
Consejo: Guarda esta guía y vuelve frecuentemente a las secciones Paso 4: Rotación de IP y Paso 5: Errores, timeouts y repeticiones. Ellas brindan la mayor estabilidad y ayudan a evitar interrupciones.
⚠️ Atención: Siempre verifica robots.txt y los términos de uso de los sitios objetivo. Si las reglas prohíben la recopilación automatizada de datos, respeta las prohibiciones y busca alternativas legales, como APIs abiertas o de pago.