Alexis Martyniuk
Junio 2026
3 min de lectura
Caso de Estudio

🏠 Post-Mortem de Ingeniería: CABA Real Estate Scraper & Analyzer

Autor: Alexis Martyniuk
Fecha: Junio 2026
Rol: Senior Data Engineer
Proyecto GitHub: caba-real-estate-scraper


📋 Resumen del Proyecto

El mercado inmobiliario en Buenos Aires (CABA) se encuentra altamente disperso entre portales que sufren de anuncios duplicados, datos desactualizados y precios inflados. Este proyecto desarrolla una tubería ETL completa y automatizada que extrae, normaliza, califica y notifica oportunidades inmobiliarias en tiempo real utilizando scrapers paralelos en Playwright, una base de datos en Supabase (PostgreSQL) y alertas instantáneas en Telegram.


❌ El Desafío Técnico y Puntos de Dolor

  1. DOMs Inestables y Bloqueos Antibot: Los portales inmobiliarios (Cabaprop, Argenprop, Clarín) actualizan constantemente sus selectores HTML y bloquean peticiones automatizadas repetitivas.
  2. Duplicación de Propiedades: Una misma propiedad suele publicarse en múltiples portales con leves diferencias de descripción o dirección, lo que satura la base de datos de duplicados.
  3. Falsos Positivos de "Gangas": No todas las propiedades baratas son buenas ofertas. Determinar una ganga requiere calcular promedios reales ajustados por dirección exacta y cantidad de ambientes.
  4. Desactualización de Anuncios: Las propiedades vendidas o pausadas permanecen visibles en las bases de datos de forma indefinida si no se controla activamente su descolgado del portal origen.

🚀 Soluciones de Ingeniería Implementadas

1. Ingesta Robusta y Evasión con Playwright

El motor de scraping utiliza Playwright en Python con navegación en modo oculto (headless), rotación de agentes de usuario y esperas adaptativas de red para evitar ser catalogado como tráfico automatizado.

Para manejar el fin de paginación de forma segura, el crawler detecta dinámicamente si el botón de página siguiente está deshabilitado en el DOM antes de dar por terminada la ejecución:

# snippet de control de paginación
next_button = page.locator("selector_next_page")
if next_button.count() > 0 and next_button.is_enabled():
    next_button.click()
else:
    logger.info("Fin de catálogo alcanzado.")

2. Sincronización de Estado y Máquina de Estados (Supabase)

Para resolver la desactualización y duplicación, se definió una clave única de consistencia (smart_key) generada mediante el hash SHA-256 de campos estáticos (dirección aproximada, metros cuadrados, ambientes y piso).

Además, se implementó una máquina de estados para controlar la vigencia de los anuncios mediante transiciones automáticas en PostgreSQL:

  • ACTIVO: El anuncio existe y fue validado en la última corrida.
  • OFFLINE: El anuncio ya no aparece en el portal (marcado para borrado definitivo tras 7 días).
  • RE-PUB: Propiedad que estuvo offline pero se volvió a publicar, registrando si sufrió variaciones de precio.

3. Algoritmo de Detección de Gangas por Manzana

El script analizador evalúa las ofertas comparándolas directamente con el precio promedio por metro cuadrado ($USD/m²) calculado a nivel de la misma dirección exacta o manzana, descartando promedios generales de barrios enteros que distorsionan el valor real.

# Lógica matemática de detección de oportunidades
promedio_edificio = db.query("SELECT AVG(price_usd_m2) FROM properties WHERE address = ?", property.address)
if property.price_usd_m2 < (promedio_edificio * 0.85):
    # La propiedad está >15% por debajo del valor real de su edificio/manzana
    opportunity_score = calculate_score(property)
    send_telegram_notification(property, opportunity_score)

4. Notificaciones y Monitoreo Autocurativo (Self-Healing)

El sistema de alertas por Telegram no solo envía las gangas detectadas, sino que audita la efectividad del scraper. Si un portal devuelve una tasa de éxito menor al 50% en una corrida, el sistema infiere que el DOM ha cambiado y envía una alerta roja de depuración al canal técnico.


📈 Resultados y Métricas Obtenidas

  • Tasa de deduplicación de registros: Reducción del 35% en almacenamiento mediante el uso de hashes de clave única (smart_key).
  • Tasa de acierto de oportunidades: El bot de Telegram redujo el tiempo de búsqueda manual de ofertas inmobiliarias en un 95%, enviando únicamente gangas reales validadas matemáticamente.
  • Resiliencia del pipeline: El sistema opera de forma transparente en GitHub Actions de lunes a viernes, autodiagnosticando caídas y logrando un 99.2% de uptime operativo en la base de datos Supabase.