Data cleansing para inmobiliaria con leads de 5 fuentes en México 2026 sigue un patrón claro: normalizar phone a E.164 con la librería phonenumbers, normalizar email lowercase trim, dedupear por phone más email como clave fuerte, aplicar fuzzy matching sobre nombre para casos donde solo coincide uno, cruzar metadata de cada fuente (Inmuebles24, Vivanuncios, Meta Ads, Google Ads, referido WhatsApp) contra el contact único para obtener atribución multi canal real. Stack típico: Python con pandas, phonenumbers, RapidFuzz, recordlinkage. Costo entre 3,000 y 15,000 USD según volumen. Pyme inmobiliaria típica encuentra 30 a 50 por ciento de duplicados en su CRM y por eso su ROI por canal es estimado, no real.
Si manejas inmobiliaria en CDMX, Monterrey, Guadalajara o Mérida y tu CRM mezcla leads de 5 fuentes distintas, esta guía te da el patrón ganador.
Las 5 fuentes típicas en inmobiliaria México 2026
| Fuente | Formato phone típico | UTM o tracking | |
|---|---|---|---|
| Inmuebles24 | 10 dígitos sin código país | A veces | UTM source inmuebles24 |
| Vivanuncios | 10 dígitos o internacional | A veces | UTM source vivanuncios |
| Meta Ads (FB e IG) | Plus52 10 dígitos | Casi siempre | Meta lead_id |
| Google Ads landing | Manual usuario | Casi siempre | GCLID más UTM |
| Referido WhatsApp | E.164 desde Twilio o Meta | Rara vez | Sin tracking estructural |
Paso 1: Inventariar tu CRM hoy
Antes de tocar nada:
- Total contacts hoy
- Phone vacíos, malformados (con guiones, espacios, sin código país)
- Email vacíos, con typos (gmial.com, hotmial.com)
- Distribución por source si lo tienes; "Unknown" si no
- Conteo de contacts creados los últimos 90 días por mes
Pyme inmobiliaria mediana en México tiene típicamente entre 5,000 y 50,000 contacts. Entre 20 y 50 por ciento son duplicados encubiertos.
Paso 2: Normalizar phone con phonenumbers
import phonenumbers
def normalize_phone_mx(raw):
if not raw:
return None
raw = ''.join(ch for ch in raw if ch.isdigit() or ch == '+')
try:
parsed = phonenumbers.parse(raw, 'MX')
if not phonenumbers.is_valid_number(parsed):
return None
return phonenumbers.format_number(parsed, phonenumbers.PhoneNumberFormat.E164)
except Exception:
return None
df['phone_e164'] = df['phone_raw'].apply(normalize_phone_mx)
Sin esto, "55 1234 5678", "plus52 55 12345678" y "5215512345678" se ven como 3 contacts distintos. Después de normalizar, se ven como uno.
Paso 3: Detectar duplicados por phone más email
df['email_norm'] = df['email_raw'].str.lower().str.strip()
# Marca duplicados por phone normalizado
dup_phone = df.duplicated(subset=['phone_e164'], keep=False)
# Marca duplicados por email normalizado
dup_email = df.duplicated(subset=['email_norm'], keep=False)
# Total con al menos un duplicado
total_dups = df[dup_phone | dup_email]
print(f"Duplicados duros: {len(total_dups)} ({len(total_dups)/len(df)*100:.1f} por ciento)")
Paso 4: Fuzzy matching para casos sin coincidencia exacta
Comprador que llenó Inmuebles24 con email Gmail y Meta Ads con email del trabajo, mismo phone:
from rapidfuzz import process, fuzz
# Para contacts sin match phone o email, fuzzy en nombre
unmatched = df[~(dup_phone | dup_email)]
names = unmatched['name'].tolist()
for idx, row in unmatched.iterrows():
matches = process.extract(row['name'], names, scorer=fuzz.ratio, limit=5)
similar = [m for m in matches if m[1] >= 90 and m[0] != row['name']]
if similar:
df.loc[idx, 'fuzzy_candidates'] = str(similar)
Threshold 90 captura typos pequeños y acentos. Casos para revisión humana, no merge automático.
Paso 5: Atribución multi canal con metadata por fuente
Una vez que tienes un contact único por persona, cruzas metadata de cada fuente:
| Contact ID único | Fuente original (primera vez) | Última fuente | Touches totales |
|---|---|---|---|
| C001 | Inmuebles24 | Meta Ads | 3 |
| C002 | Google Ads | Google Ads | 1 |
| C003 | Vivanuncios | WhatsApp referido | 4 |
Esto te da ROI real: cuánto pagaste a Meta Ads vs cuántos contacts únicos atribuidos vs cuántos cerraron compra.
El caso real: 7 de 7 inscritos trazables
Una escuela educativa en Huixquilucan llegó con dashboard CEO sin atribución real. No se sabía de dónde venía cada inscripción (formulario, bot, manual). Duplicate contacts en HubSpot por email vs phone.
Catalizadora implementó:
- Sección Atribución que cruza HubSpot metadata real (hs_object_source, hs_analytics_source, hs_analytics_first_url) con SQLite conversations por phone normalizado
- Badge visual bot OK si match encontrado
- Narrativa: TODO lo cerrado es del funnel (no separar canales)
- 7 de 7 inscritos atribuidos
- 5 trazabilidad digital (FORM o INTEGRATION en HubSpot)
- 3 con bot WhatsApp identificado
- Canales: 1 directo, 1 Instagram, 1 Google, 2 bot, 2 manual
- Inversión: 2 días integración, incluido en servicio
La misma lógica aplica a inmobiliaria con 5 fuentes. Cuando los datos se unifican, los problemas se anuncian solos: cuál portal trae leads sin valor, cuál canal cierra más, dónde se pierden leads en handoff bot a vendedor.
Stack técnico para inmobiliaria México
| Capa | Herramienta | Costo mensual |
|---|---|---|
| Captura forms web | Webhook a API propia | Incluido |
| Ingestión Inmuebles24 y Vivanuncios | API o webhooks | Incluido |
| Meta Ads leads | Meta Lead Ads API | Gratis |
| Google Ads | UTM más GCLID en landing | Gratis |
| Storage Bronze | Postgres o Supabase | 25 a 200 USD |
| Normalización | Python con phonenumbers | Servidor 50 USD |
| CRM | HubSpot Pro o CRM propio | 800 USD HubSpot o 0 propio |
| Dashboard | Metabase o Looker Studio | 0 a 50 USD |
Lo que NO debes hacer
- Mergear duplicados automático sin revisión: pierdes datos importantes (notas de visita, valuaciones distintas)
- Sin normalizar phone antes de crear contact: el problema empeora cada mes
- Sin source tracking: cuánto cuesta cada lead por canal queda estimado
- Pagar 3 herramientas distintas (HubSpot más Inmuebles24 dashboard más Meta Ads Manager) sin unificar
Próximos pasos
Si tu inmobiliaria México mezcla leads de 5 fuentes y sospechas que tu CRM tiene 30 a 50 por ciento de duplicados, un script Python lo detecta en 1 a 4 semanas. Después, un proceso continuo en el ingreso de leads evita que vuelvan.
Catalizadora arma ese diagnóstico en una llamada de 30 minutos, sin pitch deck, conversación real sobre tu operación.
- MAGIA Core construye sistemas a medida con Data Lake unificado, dedup automático, dashboards por rol e integraciones a portales en 12 semanas por 15,000 USD. Código y datos a tu nombre.
- Para inmobiliarias pequeñas con bróker independiente que quiere CRM y bot WhatsApp listos en 15 días, MAGIA Solo cubre desde 4,500 USD.