Scraping inteligente con IA: calificacion automatica de leads

AgentesNexo
··7 min lectura

El problema que resuelve este pipeline

El 80% del tiempo de un equipo comercial en LATAM se va en tres actividades que no requieren criterio humano: buscar empresas objetivo, verificar que existen y tienen actividad real, y decidir si vale la pena contactarlas. Un agente IA puede hacer las tres en paralelo y a escala, procesando 1.000 leads por menos de $1 en creditos de API.

Este articulo documenta el pipeline que usamos en AgentesNexo para calificar leads de forma automatica antes de que cualquier persona del equipo los vea.

Requisitos previos

  • Node.js 20+ con TypeScript
  • Playwright 1.45+ (scraping headless)
  • Acceso a la API de Claude (Sonnet para calificacion masiva)
  • PostgreSQL o SQLite como base de datos
  • Variables de entorno: ANTHROPIC_API_KEY, DATABASE_URL, BRAVE_API_KEY

El pipeline funciona en local o como servicio. En produccion lo corremos en un Mac mini M4 que actua como servidor de agentes 24/7.

Paso 1: Extraer datos estructurados de directorios

El primer agente recorre directorios de empresas (Google Maps Business, Clutch, directorios de camaras de comercio LATAM) y extrae campos estructurados usando Playwright mas Claude como parser de HTML.

typescript
import { chromium } from 'playwright'
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic()

async function extractBusinessData(url: string): Promise<BusinessRecord> {
  const browser = await chromium.launch({ headless: true })
  const page = await browser.newPage()

  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 })
  const html = await page.content()
  await browser.close()

  const response = await client.messages.create({
    model: 'claude-sonnet-4-5',
    max_tokens: 1024,
    messages: [{
      role: 'user',
      content: #43a047">`Extrae del siguiente HTML los datos de la empresa en JSON:
{
  "name": string,
  "sector": string,
  "employees_range": "1-10|11-50|51-200|200+",
  "country": string,
  "website": string | null,
  "description": string (max 120 chars)
}
Solo devuelve el JSON, sin texto adicional.
HTML: ${html.slice(0, 8000)}`
    }]
  })

  return JSON.parse(response.content[0].text)
}

Un proceso bien configurado extrae entre 200 y 500 empresas por hora. Si necesitas escala, lanza 4-6 workers en paralelo con el mismo codigo.

Paso 2: Enriquecer con senales de compra recientes

Con los datos basicos extraidos, el segundo agente busca senales de actividad: contrataciones recientes, expansion, tecnologias en uso. Combinamos la API de Brave Search (indexado de menos de 30 dias) con el sitio web de la empresa.

typescript
async function enrichLead(record: BusinessRecord): Promise<EnrichedLead> {
  const searchQuery = #43a047">`site:${record.website} OR "${record.name}" contratacion tecnologia 2026`

  const searchRes = await fetch(
    #43a047">`https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(searchQuery)}&count=5`,
    { headers: { 'X-Subscription-Token': process.env.BRAVE_API_KEY! } }
  )
  const results = await searchRes.json()
  const snippets = results.web?.results?.map((r: any) => r.description).join('\n') ?? ''

  const enrichment = await client.messages.create({
    model: 'claude-sonnet-4-5',
    max_tokens: 512,
    messages: [{
      role: 'user',
      content: #43a047">`Empresa: ${record.name} (${record.sector}, ${record.country})
Descripcion: ${record.description}
Actividad reciente: ${snippets}

Devuelve JSON:
{
  "has_tech_stack": boolean,
  "growth_signals": boolean,
  "budget_indicator": "low|medium|high",
  "notes": string (max 80 chars)
}`
    }]
  })

  return { ...record, enrichment: JSON.parse(enrichment.content[0].text) }
}

Agregar este paso aumenta la precision de la calificacion un 40% respecto a trabajar solo con datos estaticos del directorio.

Paso 3: Calificacion automatica contra el ICP

Este es el nucleo del sistema. Se define el Ideal Customer Profile una sola vez y el agente aplica el criterio con consistencia perfecta en cada lead, sin fatiga ni variacion de criterio entre el lead 1 y el lead 800.

typescript
const ICP_PROMPT = #43a047">`
Eres un agente de calificacion de leads para una empresa de automatizacion con IA en LATAM.
Calificamos empresas B2B con estas caracteristicas:
- 10 o mas empleados
- Sectores objetivo: salud, logistica, finanzas, retail, servicios profesionales
- Usan CRM, ERP u otras herramientas SaaS (indica presupuesto tecnologico)
- Muestran senales de crecimiento: contrataciones, expansion, nuevos productos

NO calificamos: freelancers, startups pre-revenue, gobierno, educacion publica.

Para cada lead devuelve JSON:
{
  "score": 0-100,
  "tier": "A|B|C|descarte",
  "reason": string (max 100 chars),
  "next_action": "call|email|linkedin|discard"
}`

async function qualifyLead(lead: EnrichedLead): Promise<QualifiedLead> {
  const response = await client.messages.create({
    model: 'claude-sonnet-4-5',
    max_tokens: 256,
    system: ICP_PROMPT,
    messages: [{ role: 'user', content: JSON.stringify(lead) }]
  })

  return { ...lead, qualification: JSON.parse(response.content[0].text) }
}

En produccion vemos esta distribucion tipica: 15-20% tier A, 30-35% tier B, el resto descarte. El equipo comercial trabaja solo con A y B; los C se guardan para reclasificacion en 30 dias.

Paso 4: Pipeline orquestado con rate limiting

El pipeline final encadena los tres agentes, aplica rate limiting para no saturar las APIs y escribe resultados directamente en la base de datos o los envia al CRM via webhook.

typescript
function chunks<T>(arr: T[], size: number): T[][] {
  return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
    arr.slice(i * size, i * size + size)
  )
}

async function runPipeline(urls: string[]) {
  const results: QualifiedLead[] = []

  for (const batch of chunks(urls, 10)) {
    const extracted = await Promise.all(batch.map(extractBusinessData))
    const enriched  = await Promise.all(extracted.map(enrichLead))
    const qualified = await Promise.all(enriched.map(qualifyLead))

    const tierA = qualified.filter(l => l.qualification.tier === 'A')
    await saveToCRM(tierA)         // solo tier A va al CRM inmediato
    await saveToDatabase(qualified) // todo a BD para auditoria

    results.push(...qualified)
    await new Promise(r => setTimeout(r, 1000)) // rate limit: 1s entre batches
  }

  return results
}

Costo real: procesar 1.000 leads con Claude Sonnet cuesta entre $0.80 y $1.20. Una lista de 500 leads calificados lista para el equipo de ventas: menos de $0.50.

Arquitectura del sistema

[Directorios web / CSV de leads crudos]
         |
[Agente 1: Scraping con Playwright + Claude como parser]
         |
[Agente 2: Enriquecimiento — Brave Search + senales de compra]
         |
[Agente 3: Calificacion automatica contra ICP]
         |
[BD PostgreSQL — todos los leads con score y tier]
         |
[CRM / WhatsApp / Email — solo tier A y B]

El sistema corre como servicio Node.js, se activa con un cron diario o por trigger manual. Un Mac mini M4 o cualquier VPS de $10/mes lo maneja sin problemas para volumenes de hasta 5.000 leads diarios.

Lo que aprendimos en produccion

  1. El prompt del ICP es el activo mas valioso. Dos horas refinando los criterios de calificacion dan mejor resultado que una semana optimizando el scraper. Claude es consistente cuando el ICP queda preciso.
  1. El enriquecimiento con busqueda web aumenta la precision un 40%. Sin este paso, la calificacion trabaja solo con datos estaticos del directorio. Las senales de actividad reciente son el mejor predictor de interes.
  1. Tier B no es descarte. Los leads B de hoy son A en 3 meses. Guardar todo en BD y reclasificar cada 30 dias con el mismo agente cuesta centavos y mantiene el pipeline lleno sin nuevo scraping.
  1. Rate limiting critico: 10 paralelos + 1s de pausa. Sin sleep entre batches, Playwright genera timeouts y Claude devuelve errores 529. Este es el punto dulce para procesar 1.000 leads por hora de forma estable.
  1. Separar extraccion de calificacion. Si cambia el ICP, solo se reprocesa la calificacion con los datos ya en BD. No hay que volver a ejecutar el scraper.

En resumen

  • Pipeline de 3 agentes para automatizacion con IA: scraping, enriquecimiento y calificacion automatica de leads
  • Reduce el trabajo manual de prospeccion en un 60% antes del primer contacto humano
  • Costo: menos de $1 por cada 1.000 leads procesados con inteligencia artificial para negocios
  • Tiempo de implementacion: 1-2 dias con el codigo de esta guia como base
  • El activo clave no es el codigo sino el prompt del ICP definido con precision
  • Escala sin cambios desde 100 hasta 50.000 leads por batch

Si quieres implementar esto en tu negocio sin construirlo desde cero, en AgentesNexo lo hacemos por ti. Escríbenos en agentesnexo.com o por WhatsApp al +591 67564218

Si quieres implementar esto en tu negocio sin construirlo desde cero, en AgentesNexo lo hacemos por ti. Escríbenos en agentesnexo.com o por WhatsApp al +591 67564218

Articulos relacionados