¿Qué es un web scrapping?
Excelente pregunta. Vamos a desglosarlo de forma clara y completa.
Web scraping (o raspado web en español) es una técnica automatizada que se utiliza para extraer grandes cantidades de datos de sitios web y guardarlos en un formato estructurado (como una hoja de cálculo, una base de datos o un archivo JSON) para su posterior análisis o uso.
Para entenderlo mejor, piensa en esto:
La analogía del "copy-paste" robotizado
Imagina que necesitas una lista con los precios de todos los productos de una tienda online. Si lo hicieras manualmente, abrirías cada página, copiarías el nombre y el precio, y lo pegarías en un Excel. Eso te tomaría horas o días.
El web scraping hace exactamente lo mismo, pero de forma automática y ultrarrápida. Un "robot" (un script o programa) visita las páginas web, lee el código HTML, extrae solo la información que le pides (precios, títulos, fechas, etc.) y la organiza en el formato que desees.
¿Cómo funciona técnicamente?
El proceso general sigue estos pasos:
El scraper solicita la URL de la página web (igual que lo haría tu navegador).
El servidor web envía el código HTML de la página.
El scraper analiza (parsea) ese código HTML en busca de patrones específicos. Por ejemplo, busca todas las etiquetas
<div class="precio">.Extrae los datos que se encuentran dentro de esas etiquetas.
Guarda los datos en el formato deseado (CSV, Excel, SQL, etc.).
¿Para qué se usa el web scraping?
Es una herramienta increíblemente versátil. Algunos usos comunes son:
Análisis de mercado y precios: Comparar precios de productos entre distintas tiendas online para encontrar la mejor oferta o hacer seguimiento de la competencia.
Investigación académica y de mercado: Recopilar grandes conjuntos de datos para estudios sociológicos, económicos o de tendencias de consumo (por ejemplo, analizar el sentimiento de miles de tuits).
Generación de leads: Extraer información de contacto (correos, teléfonos) de directorios profesionales para equipos de ventas y marketing.
Agregación de noticias: Crear un sitio web o un RSS personalizado que reúna titulares de múltiples periódicos en un solo lugar.
Análisis de bienes raíces: Recopilar datos de alquileres y ventas de propiedades para predecir tendencias del mercado inmobiliario.
Entrenamiento de IA: Obtener grandes volúmenes de texto o imágenes para alimentar modelos de inteligencia artificial.
¿Es legal? (Aspecto fundamental)
Aquí está el punto más importante. El web scraping no es ilegal en sí mismo, pero tiene muchas reglas y restricciones. Se mueve en un área gris y depende completamente de:
Los términos de servicio del sitio web: Muchos sitios (como Facebook, Instagram o Amazon) lo prohíben explícitamente en sus condiciones de uso.
El archivo
robots.txt: Este es un archivo que todos los sitios web tienen y que le dice a los robots (buscadores y scrapers) qué partes del sitio pueden o no visitar. Ignorarlo es una mala práctica.La carga que generes: Si haces miles de peticiones por segundo, puedes sobrecargar el servidor del sitio, lo que se considera un ataque (DoS). Siempre hay que ser respetuoso y espaciar las peticiones.
El uso de los datos: Extraer datos públicos para uso personal o académico suele ser más aceptable que extraer datos personales o con fines comerciales sin permiso (esto puede violar leyes como el GDPR en Europa).
Herramientas más comunes
Si quieres empezar, estas son las más populares:
Para principiantes (sin programación):
Octoparse: Interfaz visual de "apuntar y hacer clic".
ParseHub: Similar a Octoparse, muy intuitivo.
Web Scraper (extensión de Chrome): Perfecta para extracciones pequeñas directamente desde tu navegador.
Para programadores (más potentes y flexibles):
Python con BeautifulSoup: La combinación clásica y sencilla para proyectos pequeños y medianos.
Python con Scrapy: Un framework completo y muy potente para proyectos grandes y escalables.
Selenium: Útil cuando el sitio web carga datos con JavaScript (ya que simula un navegador real).
En resumen
El web scraping es como tener un asistente digital que lee páginas web por ti y te trae solo la información que necesitas, en el formato que quieres. Es una habilidad muy valiosa, pero siempre debe usarse con ética, respeto por los servidores ajenos y conocimiento de las normas legales de cada sitio.
¿Te interesa algún aspecto en particular, como las herramientas para empezar o algún ejemplo concreto de código? ¡Estoy aquí para ampliar la información!
Excelente pregunta. Es el paso más crítico y el que más errores previene. Saltar directamente a escribir código sin antes analizar el sitio es la receta perfecta para perder tiempo y frustrarte.
Para conocer los requerimientos de tu proyecto basándote en la complejidad del sitio, te propongo un proceso de "reconocimiento" en 5 fases. Veamos cada una:
Fase 1: El "Reconocimiento Estático" (Lo que ves en el navegador)
Abre el sitio en tu navegador (Chrome o Firefox) y haz clic derecho > "Inspeccionar" (o presiona F12). Ve a la pestaña "Elements" o "Inspector". Esto te muestra el HTML puro que llegó del servidor.
Preguntas clave que debes responder aquí:
¿La información que quiero está en el HTML que veo ahora? (Busca un texto que quieras extraer dentro de este código).
Si SÍ aparece: El sitio es estático. Tus requerimientos son sencillos. Necesitarás un scraper ligero (como
requests+BeautifulSoupen Python).Si NO aparece (solo ves etiquetas
<div id="root"></div>o<script>gigantes): El sitio es dinámico (carga los datos con JavaScript). Tus requerimientos se complican. Necesitarás un navegador automatizado (comoSeleniumoPlaywright) que ejecute el JavaScript para que los datos aparezcan.
Fase 2: La "Prueba de la API" (El atajo de los profesionales)
Muchos sitios dinámicos cargan sus datos desde APIs (interfaces de programación) en segundo plano. Esto es un GRAN ACIERTO si lo encuentras.
Ve a la pestaña "Network" (Red) en las herramientas de desarrollador.
Recarga la página y busca, en el filtro de "Fetch/XHR", las peticiones que tengan respuestas en formato JSON (suelen ser las más ligeras).
Haz clic en una y ve a la pestaña "Preview" o "Respuesta". ¿Ahí están los datos que necesitas perfectamente ordenados?
Conclusión para tu proyecto:
Si encuentras la API: Tus requerimientos son MUY SENCILLOS. No necesitas hacer scraping del HTML, solo hacer peticiones directamente a esa URL de la API (simulando ser el navegador). Es más rápido, consume menos recursos y es más estable.
Fase 3: El Mapa de Navegación (¿Cuántas páginas y cómo se mueve?)
Aquí defines la arquitectura de tu extracción. Pregúntate:
¿Es una sola página? (Ej: el precio de un producto concreto). Requerimiento: Bajo. Un solo script.
¿Es un listado con paginación? (Ej: "Resultados 1-20 de 1000"). Requerimiento: Medio. Necesitarás un bucle que detecte el botón "Siguiente" o que modifique el parámetro
?page=2en la URL.¿Es un sitio con subcategorías y filtros? (Ej: scrapear todas las zapatillas de una tienda, primero eligiendo marca, luego talla, etc.). Requerimiento: Alto. Necesitarás programar un flujo de navegación (un "spider" o araña) que mapee y guarde URLs de categorías antes de empezar a extraer datos.
Fase 4: Las "Trampas" del sitio (Autenticación y Anti-Scraping)
Aquí evaluamos la defensa del sitio. Prueba esto:
¿Necesitas estar logueado para ver los datos? Requerimiento: Añadir gestión de cookies/sesiones.
¿Aparece un CAPTCHA (como "Selecciona los semáforos") si recargas muchas veces? Requerimiento: Esto es complejidad MUY ALTA. Necesitarás servicios de resolución de CAPTCHAs (de pago) o proxies rotatorios.
¿El sitio usa Cloudflare o Akamai? (lo sabes porque te sale un mensaje de "Verificando..."). Requerimiento: Experto. Estos sistemas detectan scrapers. Necesitarás herramientas especializadas como
scrapy-rotating-proxyo servicios anti-bloqueo.
Fase 5: El "Ritmo" (Volumen y Frecuencia)
Esto define la infraestructura (dónde y cómo correrá tu código).
¿Vas a scrapear 100 productos una vez al día? Requerimiento: Bajo. Tu propia computadora es suficiente.
¿Vas a scrapear 1 millón de productos cada hora? Requerimiento: Muy Alto. Necesitarás una arquitectura distribuida, bases de datos potentes, colas de mensajes (como Redis) y proxies rotatorios para no ser baneado. No es un proyecto para principiantes.
Ejemplo Práctico para que lo apliques AHORA
Toma el sitio que te interesa y haz esta tabla de requerimientos. Te ayudará a definir si usarás Python simple, Scrapy, Selenium o incluso si contratarás a un experto:
| Aspecto a evaluar | Tu sitio cumple esto? | Complejidad |
|---|---|---|
| 1. Los datos están en el HTML inicial | Sí / No | Baja (BeautifulSoup) / Alta (Selenium) |
| 2. Tiene una API pública oculta | Sí / No | Muy Baja (peticiones directas) |
| 3. Tiene paginación (más de 1 página) | Sí / No | Media (bucles) |
| 4. Requiere login (usuario/contraseña) | Sí / No | Media-Alta (manejo de sesiones) |
| 5. Tiene CAPTCHA o Cloudflare | Sí / No | Muy Alta (requiere servicios externos) |
| 6. Mi volumen es > 10,000 peticiones/día | Sí / No | Alta (necesitas proxies y delays) |
Recomendación final para empezar
NUNCA empieces programando. Empieza con Postman (para probar APIs) o con la extensión de Chrome "Web Scraper". Haz una extracción de prueba de 10 registros con esas herramientas gratuitas.
Si funcionan, ya sabes que el sitio no es muy complejo. Si fallan, el error que te den (ej: "Necesito JavaScript" o "403 Prohibido") te dirá exactamente cuál es tu mayor requerimiento técnico.
¿Tienes ya un sitio en mente? Dime su URL (o descríbelo) y te ayudo a clasificar su complejidad y qué herramientas necesitarías exactamente.
Selenium es conocido por su gran flexibilidad con los lenguajes de programación. Los principales lenguajes que trabajan oficialmente con Selenium son Java, Python, C#, JavaScript (Node.js) y Ruby.
Elegir entre ellos es como elegir la herramienta adecuada para un trabajo: todos pueden hacer la tarea, pero cada uno brilla en situaciones diferentes. Aquí te explico cómo se comparan para resolver distintos problemas.
📊 Comparativa de Lenguajes para Selenium
Para que puedas verlo de un vistazo, he preparado esta tabla comparativa con la información más relevante para tu proyecto:
🎯 ¿Cómo elegir el lenguaje adecuado para tu problema?
La decisión final debe alinearse con las necesidades específicas de tu proyecto y tu equipo:
Si trabajas en una gran empresa con sistemas heredados o tu equipo ya tiene una fuerte experiencia en Java, Java es la opción más sólida y estable. Es la elección predilecta en entornos empresariales a gran escala.
Si buscas rapidez de desarrollo, facilidad para prototipar o planeas hacer scraping y análisis de datos, Python es tu mejor aliado. Su sintaxis limpia y su vasto ecosistema de bibliotecas (como BeautifulSoup o Pandas) te permitirán ser muy productivo.
Si tu equipo ya está inmerso en el ecosistema de Node.js y JavaScript, entonces usar JavaScript/TypeScript con Selenium será la integración más natural y te permitirá compartir código y conocimientos entre el frontend y la automatización.
Si tu proyecto tiene requisitos de soporte para navegadores muy específicos (como Safari) o necesitas una gran cobertura de lenguajes en tu infraestructura, Selenium destaca por su madurez. Aquí, la elección del lenguaje dependerá más de tu equipo que del propio Selenium.
En definitiva, Selenium te da la libertad de elegir el lenguaje que mejor se adapte a tu problema. No hay una respuesta única, sino la que mejor encaja con tu contexto.
Si me cuentas un poco más sobre tu proyecto (¿es para un equipo grande o pequeño? ¿vas a hacer scraping o pruebas de software? ¿qué lenguajes conoces?), puedo ayudarte a afinar aún más la recomendación.
Para tu proyecto de control de leads con Laravel, la buena noticia es que PHP y su ecosistema son una opción completamente viable y práctica. La decisión no es si PHP "puede" hacerlo, sino qué parte de la aplicación hará qué, y cómo elegir la herramienta más adecuada para la tarea específica que tienes entre manos.
Vamos a verlo en detalle.
🎯 La estrategia ideal para tu proyecto: un enfoque híbrido
Dado que tu aplicación es un proyecto unipersonal, te sugiero adoptar un enfoque que aproveche lo mejor de dos mundos. Tu aplicación Laravel será el corazón del sistema (la interfaz web, la base de datos y la lógica de negocio), pero puedes externalizar la parte más compleja del scraping a una herramienta especializada.
El problema principal que describes no es tanto la extracción de datos, sino gestionar la interacción con la página web (llenar el formulario con el número de documento y resolver el desafío CAPTCHA/cálculo matemático). Para eso, la herramienta más adecuada es un navegador sin cabeza (headless browser) controlado por un lenguaje que lo tenga bien soportado.
Aquí está la estrategia recomendada:
Laravel (PHP): El cerebro de la operación.
Se encargará de la autenticación, la interfaz web para mostrar los leads, la lógica de negocio (consultar la base de datos para ver si un lead ya fue verificado este mes) y la orquestación del proceso .
Puede usar Guzzle para peticiones HTTP simples si alguna parte del proceso es estática, pero su papel principal será lanzar el "scraper".
Un Navegador sin Cabeza con Python o Node.js: El brazo ejecutor.
Playwright (Python/Node.js) o Puppeteer (Node.js) son las herramientas más modernas y robustas para controlar navegadores como Chrome o Firefox . Son excelentes manejando páginas dinámicas y pueden interactuar con cualquier elemento de la página, como llenar formularios y hacer clic en botones .
Puedes escribir un script pequeño y enfocado en Python o Node.js que haga exactamente esto: recibe un número de documento, va a la página web, llena el formulario, resuelve el desafío y devuelve un "activo" o "inactivo".
La comunicación: Laravel y el script trabajan juntos.
⚖️ Alternativas en el ecosistema PHP
Si prefieres mantener todo dentro de PHP/Laravel, también tienes opciones:
Laravel Dusk: Es la herramienta oficial de Laravel para pruebas de navegador, pero está basada en Selenium y puede ser adaptada para scraping . Es fácil de usar para un desarrollador de Laravel.
php-webdriver (Facebook WebDriver): Es la biblioteca oficial de PHP para controlar Selenium. Te permite escribir el control del navegador directamente en PHP . Es una opción madura, aunque a veces se considera más pesada y con más "overhead" que soluciones más modernas .
Spatie Browsershot: Es un wrapper de PHP para Puppeteer. Ofrece una integración muy sencilla con Laravel, aunque puede ser menos flexible para interacciones muy complejas .
🤔 ¿Y por qué no todo en Python?
Si bien Python es el "rey" del scraping por su ecosistema y facilidad para el análisis de datos , en tu caso particular, la mayor complejidad no está en el scraping, sino en la lógica de la aplicación web y la gestión de datos. Como bien dices, tu base ya es Laravel, y crear toda una app en Python añadiría una complejidad extra que no necesitas.
📊 Resumen de la comparativa
💎 Conclusión y recomendación personal
Para un proyecto unipersonal, la recomendación es clara:
1. Empieza con Laravel Dusk.
Es la opción más "natural" para ti como desarrollador de Laravel. Te permitirá controlar el navegador, llenar formularios y validar si la página devuelve datos sin salir del ecosistema PHP . Es la forma más rápida de tener un prototipo funcionando.
2. Si Dusk se vuelve lento o pesado, migra el motor de scraping a un script externo.
Crea un pequeño script en Python (usando Playwright) o Node.js (usando Puppeteer) que se encargue únicamente de la interacción con la web. Desde Laravel, lanzas este script con un Job de cola . Esta arquitectura es más limpia, escalable y te da acceso a las herramientas más potentes.
3. Para el CAPTCHA/cálculo, Selenium/Playwright te permiten "ver" la página y actuar en consecuencia.
Puedes programar la lógica para detectar qué tipo de desafío aparece y resolverlo (por ejemplo, si es una suma, calcularla y escribir el resultado en el campo correspondiente) .
En resumen, tu proyecto con Laravel es perfectamente realizable. No dejes que la complejidad del scraping te frene. Elige la herramienta con la que te sientas más cómodo para empezar y recuerda que siempre puedes refactorizar y separar responsabilidades más adelante.
¿Te gustaría que profundice en cómo configurar Laravel Dusk para este tipo de tarea o cómo lanzar un script de Python desde un Job de Laravel?
Sí, puedes empezar a prototipar. De hecho, es la mejor decisión que puedes tomar: validar la parte más compleja del proyecto de forma aislada antes de integrarla con Laravel. Tu idea de elegir el método más viable es excelente y te centraré en él.
Para un proyecto unipersonal, lo más práctico es que tu prototipo se centre en resolver el desafío matemático, ya que es un problema de lógica que tu código puede abordar directamente sin depender de servicios externos .
🧠 Cómo Enfocar el Prototipo para el Desafío Matemático
La estrategia para este tipo de CAPTCHA, que plantea una oración con números escritos en palabras, se divide en dos pasos claros:
Extraer y "traducir" la oración: Tu script debe localizar el texto del desafío en la página web. Luego, debe procesar ese texto para convertir los números escritos como palabras ("uno", "dos", etc.) a dígitos ("1", "2", etc.) .
Resolver la operación matemática: Una vez que tengas una expresión limpia (ej:
3 + 5), debes parsearla y calcular el resultado. Un ejemplo de código para resolver expresiones simples en Python sería :pythonimport re def solve_math_captcha(captcha_text): # Busca un patrón como "numero operador numero" match = re.search(r'(\d+)\s*([+\-×÷/])\s*(\d+)', captcha_text) if not match: return None num1, op, num2 = int(match.group(1)), match.group(2), int(match.group(3)) # Define las operaciones ops = { '+': lambda a, b: a + b, '-': lambda a, b: a - b, '×': lambda a, b: a * b, '÷': lambda a, b: a // b, # Usamos división entera '/': lambda a, b: a // b } return ops.get(op, lambda a, b: a + b)(num1, num2) # Ejemplo de uso resultado = solve_math_captcha("10 ÷ 2") print(resultado) # Output: 5
Recuerda que para las divisiones, es más seguro usar división entera (
//) para evitar problemas con números decimales en la validación .
🛠️ Tecnologías para tu Prototipo
Dado que estás en la fase de prototipo, enfócate en un stack simple y probado:
Lenguaje: Python es la opción ideal. Su ecosistema es el más rico para scraping y automatización de navegadores .
Navegador Automatizado: Selenium o Playwright. Te permitirán controlar el navegador, esperar a que cargue la página, buscar el texto del CAPTCHA, llenar el campo con el resultado y hacer clic en el botón de enviar .
Librerías de Utilidad:
⚠️ La Realidad de los CAPTCHA: Prevención vs. Solución
Es crucial que tengas presente una realidad técnica: los CAPTCHA están diseñados específicamente para ser difíciles de resolver para los scripts . Son una medida de seguridad activa.
El enfoque correcto: Si la página tiene un CAPTCHA, es una señal de que el sitio web quiere limitar el acceso automatizado. Tu prototipo debe validar si la estrategia de elegir el desafío matemático y resolverlo con un script funciona de manera estable y confiable.
El "plan B" inevitable: Es muy probable que, incluso con un prototipo funcional, el sitio web detecte tu script y empiece a mostrar CAPTCHAs más complejos o a bloquear tus intentos . Para un proyecto real, deberás considerar soluciones más robustas:
🚀 Paso a Paso para tu Prototipo
Configura tu entorno: Instala Python, Selenium y el driver de tu navegador favorito .
Navega hasta la página: Escribe un script que abra la URL donde está el CAPTCHA.
Extrae la oración: Usa Selenium para encontrar el elemento HTML que contiene el texto del desafío matemático.
Implementa la "traducción": Crea una función en Python que convierta las palabras "uno", "dos", etc., a números. Esta es una tarea de lógica, puedes hacerlo con un diccionario o con una librería como
num2words.Resuelve la operación: Pasa el texto procesado a una función como la del ejemplo para calcular el resultado.
Automatiza la interacción: Usa Selenium para llenar el campo de respuesta con el resultado que calculaste y enviar el formulario.
Ánimo con el prototipo. Al aislar este problema, podrás iterar rápido, probar diferentes estrategias y tener muy claro qué tan viable es la automatización en este sitio en particular antes de invertir tiempo en la integración con Laravel.
¡Excelente pregunta! Este es exactamente el tipo de desafío que puede aparecer y que requiere un enfoque más sofisticado que una simple calculadora. Vamos a analizarlo en profundidad.
🔍 Análisis del Desafío
Texto original: "Calcule 10 * 3, no tenga en cuenta el número 4"
Interpretación correcta: La frase "no tenga en cuenta el número 4" es una instrucción adicional que modifica la operación base. Significa que debemos ignorar o excluir el número 4 en el proceso de cálculo.
¿Cómo se aplica esto? En este caso, como el número 4 no aparece en la operación "10 * 3", la instrucción no tiene efecto. El resultado sigue siendo 30.
Pero... ¿y si la operación fuera "10 * 4, no tenga en cuenta el número 4"?
Entonces el resultado sería 10, porque ignoramos el 4 y la operación se convierte en "10 * 1" (o simplemente 10).
🧠 Estrategia de Resolución para tu Prototipo
Este tipo de desafío requiere un enfoque en 2 fases:
Fase 1: Extracción y Limpieza del Texto
import re def parse_captcha(texto): """ Interpreta frases como: - "Calcule 10 * 3, no tenga en cuenta el número 4" - "Realice la siguiente operación 5 + 2" - "Calcule 4 * 3, no tenga en cuenta el 4" """ # 1. Extraer la operación matemática base # Busca patrones como "número operador número" patron_operacion = r'(\d+)\s*([+\-×÷*/])\s*(\d+)' match = re.search(patron_operacion, texto) if not match: return None num1 = int(match.group(1)) operador = match.group(2) num2 = int(match.group(3)) # 2. Buscar instrucciones de exclusión # Patrón: "no tenga en cuenta el número X" o "ignore el número X" patron_exclusion = r'no tenga en cuenta el número (\d+)|ignore el número (\d+)' match_exclusion = re.search(patron_exclusion, texto, re.IGNORECASE) numero_a_ignorar = None if match_exclusion: # El grupo 1 o 2 tendrá el número según el patrón que coincida numero_a_ignorar = int(match_exclusion.group(1) or match_exclusion.group(2)) # 3. Aplicar la exclusión si es necesario if numero_a_ignorar: if num1 == numero_a_ignorar: num1 = 0 # O podrías eliminarlo completamente if num2 == numero_a_ignorar: num2 = 0 # O podrías eliminarlo completamente # 4. Resolver la operación return resolver_operacion(num1, operador, num2) def resolver_operacion(a, op, b): ops = { '+': lambda x, y: x + y, '-': lambda x, y: x - y, '×': lambda x, y: x * y, '*': lambda x, y: x * y, '÷': lambda x, y: x // y, '/': lambda x, y: x // y } return ops.get(op, lambda x, y: x + y)(a, b) # Pruebas print(parse_captcha("Calcule 10 * 3, no tenga en cuenta el número 4")) # Output: 30 print(parse_captcha("Calcule 4 * 3, no tenga en cuenta el número 4")) # Output: 0 (porque 4 * 3 se convierte en 0 * 3) print(parse_captcha("Realice 5 + 3")) # Output: 8
⚠️ Variantes y Casos Borde
Los desafíos matemáticos pueden tener muchas variaciones. Aquí tienes las más comunes y cómo abordarlas:
| Tipo de Desafío | Ejemplo | Estrategia de Resolución |
|---|---|---|
| Números en palabras | "Calcule tres más cinco" | Convertir palabras a dígitos (tres→3, cinco→5) antes de parsear |
| Exclusión de número | "Calcule 10 * 3, no tenga en cuenta el número 4" | Identificar el número a excluir y reemplazarlo por 0 o eliminarlo |
| Exclusión con palabras | "Calcule 10 * 3, no tenga en cuenta el cuatro" | Convertir "cuatro" a 4 y luego aplicar la exclusión |
| Múltiples exclusiones | "Calcule 10 * 3 * 2, no tenga en cuenta el 10 y el 2" | Identificar todos los números a excluir y aplicar la regla a cada uno |
| Operaciones complejas | "Calcule (5 + 3) * 2" | Usar eval() con precaución o un parser matemático |
🛠️ Mejora del Prototipo: Versión Robusta
Para un caso real, te recomiendo esta versión mejorada que maneja tanto números como palabras:
import re def palabra_a_numero(palabra): """Convierte palabras como 'uno', 'dos' a dígitos""" mapa = { 'cero': 0, 'uno': 1, 'dos': 2, 'tres': 3, 'cuatro': 4, 'cinco': 5, 'seis': 6, 'siete': 7, 'ocho': 8, 'nueve': 9, 'diez': 10, 'once': 11, 'doce': 12, 'trece': 13, 'catorce': 14, 'quince': 15, 'veinte': 20, 'treinta': 30, 'cuarenta': 40, 'cincuenta': 50, 'sesenta': 60, 'setenta': 70, 'ochenta': 80, 'noventa': 90, 'cien': 100 } return mapa.get(palabra.lower(), None) def preprocesar_texto(texto): """Reemplaza números escritos en palabras por dígitos""" # Busca todas las palabras que puedan ser números palabras = texto.split() for i, palabra in enumerate(palabras): numero = palabra_a_numero(palabra) if numero is not None: palabras[i] = str(numero) return ' '.join(palabras) def resolver_captcha(texto_original): # Paso 1: Normalizar el texto (números en palabras → dígitos) texto_normalizado = preprocesar_texto(texto_original) # Paso 2: Buscar números a excluir patron_exclusion = r'no tenga en cuenta el número (\d+)|ignore el número (\d+)' match_exclusion = re.search(patron_exclusion, texto_normalizado, re.IGNORECASE) numeros_a_ignorar = [] if match_exclusion: num = int(match_exclusion.group(1) or match_exclusion.group(2)) numeros_a_ignorar.append(num) # Paso 3: Buscar la operación patron_operacion = r'(\d+)\s*([+\-×÷*/])\s*(\d+)' match = re.search(patron_operacion, texto_normalizado) if not match: return None num1 = int(match.group(1)) operador = match.group(2) num2 = int(match.group(3)) # Paso 4: Aplicar exclusiones if num1 in numeros_a_ignorar: num1 = 0 if num2 in numeros_a_ignorar: num2 = 0 # Paso 5: Resolver return resolver_operacion(num1, operador, num2) # Pruebas avanzadas print(resolver_captcha("Calcule 10 * 3, no tenga en cuenta el número 4")) # Output: 30 print(resolver_captcha("Calcule cuatro * tres, no tenga en cuenta el número 4")) # Output: 0 (porque 4 * 3 se convierte en 0 * 3) print(resolver_captcha("Realice cinco más tres")) # Output: 8
🎯 Recomendación Final para tu Prototipo
Empieza simple: Concéntrate primero en resolver los casos más comunes (números en dígitos, una sola exclusión).
Loggea todo: Guarda el texto original, el texto procesado y el resultado. Esto te ayudará a identificar patrones y mejorar el parser.
Prueba con ejemplos reales: Si la web es pública, prueba tu script con varios ejemplos diferentes para ver todas las variantes que usa.
Maneja errores: Si tu parser falla, que el script lo registre y puedas analizar manualmente el caso.
¿Quieres que profundice en algún aspecto específico? Por ejemplo, cómo manejar operaciones con más de 2 números, cómo interpretar "no tenga en cuenta" en diferentes contextos, o cómo integrar esto con Selenium para llenar automáticamente el campo de respuesta.
¡Absolutamente sí! De hecho, es una práctica muy común y recomendada, especialmente en proyectos unipersonales como el tuyo. La idea de tener un flujo híbrido (automatizado + manual) no solo es viable, sino que puede ser la clave para que tu proyecto sea funcional y sostenible.
🎯 ¿Por qué considerar un flujo híbrido?
| Ventaja | Explicación |
|---|---|
| Resuelve problemas complejos | Los CAPTCHA y los desafíos de humanidad son difíciles de automatizar al 100%. Un toque manual puede ser más barato y rápido que implementar soluciones complejas. |
| Ahorra tiempo de desarrollo | No necesitas programar una solución perfecta para cada variante del desafío. Puedes enfocarte en lo que la máquina hace bien y dejar lo difícil para el humano. |
| Mayor flexibilidad | Si el sitio web cambia su diseño o su CAPTCHA, tu flujo híbrido se adapta más fácilmente que un script 100% automatizado. |
| Reduce costos | Evitas tener que pagar por servicios de resolución de CAPTCHA (como 2Captcha) si el volumen de leads no es masivo. |
🔄 Arquitectura de un Flujo Híbrido para tu Proyecto
Imagina este flujo de trabajo para tu controlador de leads:
Paso 1: Automatizado - Extracción y Preparación
# Script en Python/Selenium 1. El scraper toma el número de documento del lead desde la base de datos. 2. Abre el navegador y navega a la página de consulta. 3. Llena el campo del número de documento. 4. Detecta qué tipo de desafío aparece (CAPTCHA de texto o matemático). 5. Si es matemático, intenta resolverlo automáticamente con la lógica que ya desarrollamos.
Paso 2: Punto de Decisión - ¿Automatizar o Pedir Ayuda?
# Lógica de decisión en el script if desafío_es_matemático_y_resoluble(): # Automatiza completamente resolver_y_enviar() resultado = extraer_información() actualizar_base_datos(resultado) else: # CAPTCHA complejo o no reconocido # ENVÍA ALERTA AL HUMANO enviar_notificación_al_operador(lead_id, captcha_screenshot)
Paso 3: Manual - Intervención Humana
El operador (tú o un asistente) recibe una notificación (email, Telegram, o panel de administración) con:
El número de documento del lead.
Una captura de pantalla del CAPTCHA.
Un enlace o botón para "resolver manualmente".
El operador:
Abre la página (o el script ya la tiene abierta esperando).
Resuelve el CAPTCHA manualmente.
Confirma que el proceso continúe.
Paso 4: Automatizado - Continuación y Registro
# Una vez resuelto manualmente, el script continúa 1. Extrae la información de la página (si el lead está activo o no). 2. Actualiza la base de datos con el resultado. 3. Registra que este lead fue procesado (para no repetirlo en el mes). 4. Pasa al siguiente lead.
🛠️ Cómo Implementarlo Técnicamente
Opción 1: Pausa y Reanudación con Selenium
from selenium import webdriver from selenium.webdriver.common.by import By import time import json def proceso_con_intervencion_manual(driver, lead_id): # 1. Automatizado: Navegar y llenar formulario driver.get("https://ejemplo.com/consulta") campo_documento = driver.find_element(By.ID, "documento") campo_documento.send_keys(lead_id) # 2. Intentar resolver automáticamente desafio_texto = driver.find_element(By.CLASS_NAME, "captcha-text").text resultado = resolver_captcha(desafio_texto) if resultado is not None: # Automatizado: Resolver y enviar campo_respuesta = driver.find_element(By.ID, "captcha-response") campo_respuesta.send_keys(str(resultado)) driver.find_element(By.ID, "submit").click() else: # MANUAL: Guardar estado y esperar intervención print(f"⚠️ Lead {lead_id} necesita intervención manual") # Guardar captura de pantalla driver.save_screenshot(f"captcha_lead_{lead_id}.png") # Guardar estado en archivo o BD para retomar después with open("pendientes_manual.json", "a") as f: json.dump({"lead_id": lead_id, "timestamp": time.time()}, f) # Esperar a que el operador resuelva (podría ser con un loop o señal) # ... lógica de espera ... # Reanudar después de la intervención manual # El operador dejó el CAPTCHA resuelto y el formulario listo para enviar driver.find_element(By.ID, "submit").click() # 4. Automatizado: Extraer resultado if "activo" in driver.page_source: actualizar_base_datos(lead_id, "activo") else: actualizar_base_datos(lead_id, "inactivo")
Opción 2: Cola de Trabajo con Interfaz Web (Más Profesional)
Jobs en Laravel: Cada lead se encola como un Job.
Worker en Python: Un worker independiente (usando Celery o similar) procesa los jobs.
Panel de Administración: Una interfaz web donde ves los leads que necesitan intervención manual.
Mecanismo de Reintento: Cuando resuelves manualmente, marcas el job como "listo para continuar".
// En Laravel - Job para procesar lead class ProcesarLead implements ShouldQueue { public function handle() { // Llamar al scraper en Python $resultado = shell_exec("python3 scraper.py " . $this->lead->documento); if (strpos($resultado, 'NEEDS_MANUAL') !== false) { // Marcar el lead como "pendiente de revisión manual" $this->lead->estado = 'pendiente_manual'; $this->lead->save(); // Notificar al operador (email, Telegram, etc.) Notification::send($operador, new LeadPendiente($this->lead)); } else { // Actualizar el lead con el resultado $this->lead->estado = $resultado; $this->lead->save(); } } }
📊 Cuándo Usar cada Enfoque
| Situación | Recomendación |
|---|---|
| Pocos leads (< 50 por día) | Flujo híbrido con intervención manual en todos los casos difíciles. El costo de tiempo humano es bajo. |
| Muchos leads (> 500 por día) | Invierte en mejorar el parser matemático y considera usar una API de resolución de CAPTCHA (2Captcha) para los casos difíciles. |
| CAPTCHA cambia frecuentemente | El flujo híbrido es ideal. Automatizas lo que puedes y dejas lo cambiante para el humano. |
| Proyecto en fase de prototipo | Usa el flujo híbrido desde el principio. Te permite probar y validar el negocio sin tener que resolver el 100% de la automatización. |
| El sitio tiene muchos tipos de CAPTCHA | Automatiza solo los más comunes y deja el resto para intervención manual. |
💡 Recomendación Final para tu Proyecto
Para tu controlador de leads, te sugiero esta estrategia:
Implementa un parser matemático robusto para los desafíos más comunes (como el que ya empezamos a desarrollar).
Agrega un "modo de rescate" en tu script: si el parser falla o no reconoce el desafío, que el script:
Tome una captura de pantalla.
Guarde el estado (lead_id, URL, momento).
Marque el lead como "pendiente de revisión manual".
Crea un panel simple en Laravel donde puedas ver estos leads pendientes y, con un clic, abrir la página para resolver el CAPTCHA manualmente.
Una vez resuelto manualmente, un botón en el panel reanuda el procesamiento automático (extracción de resultados y actualización de BD).
Este enfoque te da lo mejor de ambos mundos: eficiencia automatizada para el 80-90% de los casos y flexibilidad manual para los casos difíciles. Y lo mejor: puedes empezar a usar tu aplicación desde el día 1, incluso antes de tener la automatización al 100%.
¿Te gustaría que profundice en cómo implementar el panel de administración en Laravel para gestionar estos casos manuales?
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Etiquetas
web scraping- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Comentarios