En resumen: Idealista es el mayor portal inmobiliario de España, Italia y Portugal, pero cuenta con un potente sistema antibots que bloquea rápidamente a los rastreadores poco sofisticados. Esta guía te explica paso a paso cómo extraer datos de Idealista de principio a fin en Python, abarcando el mapeo del sitio, el uso de Selenium con undetected-chromedriver, el manejo de DataDome, la rotación de proxies y la exportación de datos limpios, incluyendo medidas de seguridad para entornos de producción que los competidores suelen pasar por alto.
Introducción
Si has dedicado tiempo a intentar averiguar cómo extraer datos de Idealista, ya sabes que el manual de instrucciones es breve y brutal: envía unas cuantas solicitudes limpias, te bloquean, cambias de user-agent, te vuelven a bloquear, te sale un captcha y empiezas de nuevo. Idealista es el portal inmobiliario dominante en España, Portugal e Italia, con millones de anuncios de venta y alquiler, lo que lo convierte en una mina de oro para analistas de mercado, agentes inmobiliarios y equipos de proptech. También es uno de los sitios mejor protegidos de su categoría.
Esta guía está dirigida a desarrolladores de Python de nivel intermedio que buscan una receta probada en la práctica, no un fragmento de código. Primero aprenderás el contexto legal y técnico, luego seguirás paso a paso un flujo de trabajo concreto con Selenium y undetected-chromedriver, y finalmente incorporarás proxies, gestión de captchas, deduplicación y seguimiento incremental, con las realidades de producción que la mayoría de los tutoriales omiten.
¿Por qué extraer datos de Idealista y qué datos realmente vale la pena extraer?
Idealista es uno de los mayores mercados inmobiliarios del sur de Europa, con millones de anuncios de venta y alquiler en sus sitios web de España, Italia y Portugal. Para la investigación de inversores, los modelos de precios comparativos y el enriquecimiento de clientes potenciales para las agencias, esa presencia es difícil de replicar solo a partir de las API públicas, razón por la cual tantos equipos se preguntan, en primer lugar, cómo extraer datos de Idealista.
Cuando planifiques un scraping, decide de antemano qué campos necesitas realmente. La ficha del anuncio y las páginas de detalles suelen mostrar:
- Título y URL del anuncio (el slug canónico
/inmueble/<id>/) - Precio y moneda, además del precio por metro cuadrado en las páginas de detalles
- Superficie en m², número de habitaciones y baños
- Texto descriptivo, fecha de publicación y fecha de actualización
- Tipo de agente o propietario (particular o agencia), con teléfono y botones de contacto
- Fotos, planos y, en ocasiones, enlaces a visitas virtuales
- Coordenadas aproximadas y metadatos del barrio
Los sitios web italiano (idealista.it) y portugués (idealista.pt) suelen reflejar el diseño del español, por lo que un único diseño de scraper suele adaptarse a los tres con pequeños ajustes en los selectores. Volveremos a abordar esas diferencias en la sección de resolución de problemas.
¿Es legal el scraping de Idealista? Normas básicas de cumplimiento
Los datos de anuncios públicos se consideran generalmente de libre acceso cuando se recopilan a un ritmo razonable, pero los términos de servicio de Idealista y el RGPD de la UE cambian las reglas del juego en cuanto se tocan los datos personales. Los nombres de los agentes, los números de teléfono y las direcciones de correo electrónico son datos personales según el RGPD, por lo que almacenarlos a gran escala suele requerir una base legal documentada, límites de conservación y una ruta de eliminación de datos.
Medidas de seguridad prácticas: respeta robots.txt, limita el tráfico de forma agresiva, evita las áreas que requieren inicio de sesión y elimina los datos de contacto personales de cualquier conjunto de datos que redistribuyas. Considera esta sección como una orientación más que como un consejo legal, y consulta con tu asesor legal cualquier aspecto sensible antes de la producción. La postura legal en este caso es realmente controvertida, así que verifica el alcance actual del RGPD para tu caso de uso específico antes de implementar un rastreador a gran escala.
Cómo detecta Idealista los bots: DataDome, huellas digitales y límites de frecuencia
La mayoría de los informes públicos atribuyen el captcha intersticial de Idealista a DataDome, un servicio comercial de mitigación de bots. Considera esa atribución como un consenso de la comunidad más que como una declaración oficial, ya que Idealista no publica su pila de detección.
La detección se produce en capas, y comprender cada una de ellas marca la diferencia entre un scraper que sobrevive una semana y uno bloqueado en una hora:
- Huellas digitales TLS y JA3.
requestsy muchas bibliotecas HTTP producen una firma de handshake TLS fácilmente distinguible de una sesión real de Chrome. Incluso con un User-Agent perfecto, el orden de cifrado te delata. - Coherencia de los encabezados. Los motores de detección de bots comprueban que
Accept,Accept-Language,sec-ch-ua, yUser-Agentcoincidan entre sí. Un User-Agent de Chrome 120 junto con unsec-ch-ua-platformes una señal reveladora. - Desafíos de JavaScript. DataDome sirve una pequeña carga útil de JS que sondea
navigator.webdriver, hash de lienzos, renderizadores WebGL y señales de sincronización. Chrome sin interfaz gráfica y Selenium estándar fallan en varios de ellos por defecto. - Señales de comportamiento e IP. La velocidad, la navegación sin ratón, los rangos ASN de centros de datos y las cookies reutilizadas se tienen en cuenta en una puntuación de riesgo que activa el captcha.
Tu bot necesita una huella digital de navegador real, encabezados plausibles, IP residenciales o móviles y un ritmo similar al de un humano. Ninguna solución por sí sola es suficiente.
Elección de una pila de scraping: requests/HTTPX frente a Selenium frente a una API de scraping
No hay una respuesta universalmente correcta sobre cómo extraer datos de Idealista a gran escala; la elección adecuada depende del volumen, el presupuesto y la cantidad de JavaScript que estés dispuesto a renderizar. Aquí tienes una matriz de decisión rápida que puedes pegar en un documento de planificación.
|
Enfoque |
Ideal para |
Velocidad |
Resistencia a DataDome |
Mantenimiento |
|---|---|---|---|---|
|
|
Pequeñas consultas puntuales |
Rápido |
Bajo |
Bajo hasta que se bloquee |
|
|
Rastreo medio, compatible con asíncrono |
Muy rápido |
Bajo a medio |
Moderado |
|
Selenium + undetected-chromedriver |
Extracción fiable por página |
Lento |
Media |
Alto (desviación del controlador) |
|
API de scraping gestionada |
Escala de producción, sin intervención |
Variable |
Alta |
Bajo |
Las pilas HTTP puras son la opción más económica cuando funcionan, pero se desmoronan en cuanto Idealista se convierte en un reto de JS. Selenium con undetected-chromedriver te ofrece una huella digital de navegador real y ejecución DOM, a costa de ser significativamente más lento y consumir más memoria. Una API gestionada oculta por completo la capa de proxy y resolución de retos, lo cual es la decisión acertada una vez que superas la capacidad de una sola máquina. La mayoría de los equipos de producción acaban combinando estas opciones: una ruta HTTP rápida para páginas sencillas, un navegador de respaldo para las más complejas y una API de scraping como red de seguridad.
Configuración de tu proyecto Python y dependencias
Necesitarás Python 3.10 o una versión más reciente, un virtualenv limpio y dependencias fijadas. El frontend de Idealista cambia a menudo, por lo que fijar las versiones facilita el diagnóstico posterior de regresiones.
python -m venv .venv
source .venv/bin/activate
pip install selenium==4.* undetected-chromedriver selenium-wire httpx parsel tenacity python-dotenvUna configuración práctica:
idealista-scraper/
├── .env # proxy credentials, API keys
├── config.py # constants, base URLs
├── scraper/
│ ├── driver.py # uc.Chrome factory + waits
│ ├── crawl.py # provinces → municipalities → listings
│ └── parse.py # XPath/CSS extractors
├── storage.py # JSON/CSV/SQLite writers
└── main.pyFija la versión principal de Chrome con respecto a tu undetected-chromedriver ; las discrepancias son la causa más común de fallos silenciosos.
Mapeo de la estructura de URL de Idealista: página de inicio, provincias, municipios, búsqueda, propiedad
Antes de escribir un solo selector, recorre el sitio manualmente. El esquema de URL de Idealista es bastante regular una vez que ves el patrón, y un mapa mental claro te evita volver a rastrear los mismos nodos.
La jerarquía es más o menos así:
- Página de inicio:
https://www.idealista.com/(y.it,.ptpara las versiones en italiano y portugués) - Directorio de provincias: enlazado desde la parte inferior de la página de inicio
- Directorio de municipios: debajo de cada provincia, una página con la lista de municipios
- Páginas de anuncios:
/venta-viviendas/<municipality>/en venta,/alquiler-viviendas/<municipality>/en alquiler (los patrones de URL de alquiler y de IT/PT suelen ser similares, pero compruébalo primero en una página activa) - Paginación:
pagina-2.htm,pagina-3.htm, añadida a la URL del anuncio - Detalles de la propiedad:
/inmueble/<id>/, el identificador canónico único del anuncio - Orden por fecha: añadir
?ordenado-por=fecha-publicacion-descpara mostrar primero las propiedades recién publicadas
Internaliza ese inmueble/<id> slug; el resto del artículo lo utiliza como clave de deduplicación y eje de seguimiento de cambios. Una referencia sólida de selectores CSS resulta invaluable aquí cuando los selectores cambian.
Cómo extraer datos de Idealista con Selenium y undetected-chromedriver
Con el mapa de URL en mano, puedes poner en marcha el rastreador propiamente dicho. El plan: inicia un Chrome parcheado a través de undetected-chromedriver, navegar a la página de inicio y utilizar esperas explícitas para confirmar que el DOM se ha renderizado antes de consultarlo. Los siguientes cuatro pasos construyen el rastreador en un barrido de arriba abajo, desde las provincias hasta los municipios, pasando por las fichas de anuncios y la paginación.
Paso 1: Extraer la lista completa de provincias de la página de inicio
La página de inicio en español muestra un directorio de provincias cerca del pie de página. Recogemos cada enlace dentro de ese bloque, almacenamos el nombre visible y guardamos la URL absoluta para el siguiente paso.
import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def make_driver():
opts = uc.ChromeOptions()
opts.add_argument("--window-size=1366,900")
# use_subprocess=True is currently required to avoid a destructor
# bug in some undetected-chromedriver builds; verify against the
# upstream repo before pinning, since package internals change often.
return uc.Chrome(options=opts, use_subprocess=True)
def fetch_provinces(driver):
driver.get("https://www.idealista.com/")
WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div.locations-list"))
)
anchors = driver.find_elements(
By.XPATH, "//div[contains(@class,'locations-list')]//a"
)
return {a.text.strip(): a.get_attribute("href") for a in anchors if a.text.strip()}Es casi seguro que la primera llamada se encontrará con un captcha de DataDome, así que envuélvela con un gancho de resolución manual (que veremos más adelante) en la primera ejecución. Una vez que tu sesión tenga una cookie limpia, el resto del rastreo suele fluir sin problemas.
Paso 2: Rastrear cada provincia para obtener sus municipios
Cada página de provincia muestra sus municipios a través de un location_list bloque. Recorremos el diccionario del paso 1 y adjuntamos el nombre y la URL de cada municipio debajo de su provincia matriz.
def fetch_municipalities(driver, provinces):
out = {}
for name, url in provinces.items():
driver.get(url)
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.ID, "location_list"))
)
anchors = driver.find_elements(By.XPATH, "//ul[@id='location_list']//a")
out[name] = {
"url": url,
"municipalities": [
{"name": a.text.strip(), "url": a.get_attribute("href")}
for a in anchors if a.text.strip()
],
}
time.sleep(random.uniform(2.5, 6.0)) # polite pacing
return outHay dos cosas que vale la pena destacar: los tiempos de espera aleatorios imitan la navegación humana de forma más convincente que los retrasos fijos, y deberías guardar este diccionario anidado en el disco después de cada provincia para que un fallo en la provincia número 30 no te cueste las 29 anteriores.
Paso 3: Analizar las fichas de propiedades (título, precio, superficie, descripción, URL)
Las páginas de listado muestran un article.item nodo por propiedad, con elementos secundarios estructurados para los campos canónicos. Los patrones XPath que se muestran a continuación utilizan contains(@class, ...) en lugar de la igualdad estricta porque Idealista a veces añade clases modificadoras a sus fichas.
def parse_listing_page(driver):
cards = driver.find_elements(By.XPATH, "//article[contains(@class,'item')]")
rows = []
for c in cards:
try:
link = c.find_element(By.XPATH, ".//a[contains(@class,'item-link')]")
url = link.get_attribute("href")
title = link.text.strip()
price = c.find_element(
By.XPATH, ".//span[contains(@class,'item-price')]"
).text.strip()
details = [
d.text.strip() for d in c.find_elements(
By.XPATH, ".//span[contains(@class,'item-detail-char')]/span"
)
]
description = c.find_element(
By.XPATH, ".//div[contains(@class,'item-description')]"
).text.strip()
rows.append({
"id": url.rstrip("/").split("/")[-1],
"url": url, "title": title, "price": price,
"details": details, "description": description,
})
except Exception:
# Sponsored or malformed cards: skip rather than abort.
continue
return rowsDos notas de producción. En primer lugar, Idealista intercala tarjetas de anuncios que parecen casi idénticas a las orgánicas; el try/except en torno a cada ficha evita que un nodo erróneo bloquee la página. Segundo, los selectores varían; es probable que haya que actualizar estos XPath cada dos meses. Guárdalos en un único parse.py módulo para que la comparación sea fácil.
Paso 4: Sigue la paginación a través del enlace «Siguiente»
Idealista utiliza un esquema de paginación numérica con un Siguiente enlace «Siguiente» envuelto en li.next. Algunos tutoriales recurren a la siguiente URL hasta que desaparece, pero la recursión ilimitada es la forma de agotar los límites de velocidad y alcanzar el techo de recursión de Python en municipios densos. Limita el bucle en su lugar.
MAX_PAGES = 40
def crawl_municipality(driver, start_url, max_pages=MAX_PAGES):
rows, url, page = [], start_url, 0
while url and page < max_pages:
driver.get(url)
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.XPATH, "//main"))
)
rows.extend(parse_listing_page(driver))
try:
next_link = driver.find_element(
By.XPATH, "//li[contains(@class,'next')]/a"
)
url = next_link.get_attribute("href")
except Exception:
url = None
page += 1
time.sleep(random.uniform(3.0, 7.0))
return rowsUn límite de 40 páginas se ajusta aproximadamente al propio límite de paginación profunda de Idealista y mantiene a cada trabajador dentro de unos límites. Si realmente necesitas más, divide la búsqueda por rango de precios o tipo de propiedad y ejecuta esas subconsultas en paralelo en lugar de profundizar en un único conjunto de resultados.
Resolver los captchas de DataDome a mitad de sesión sin perder el estado
Cualquiera que aprenda a extraer datos de Idealista acabará encontrándose con el intersticial de DataDome. La buena noticia, confirmada de forma anecdótica en varias comunidades de scrapers, es que una vez que resuelves el desafío en una sesión, normalmente no vuelve a aparecer durante el resto de esa sesión de navegación. Puedes aprovechar eso con algunas tácticas concretas.
La más sencilla es un hook de resolución manual para el desarrollo:
def open_with_captcha_pause(driver, url):
driver.get(url)
if "captcha" in driver.page_source.lower() or "datadome" in driver.page_source.lower():
input("Solve the captcha in the browser, then press Enter to continue...")Para cualquier cosa que vaya más allá de un caso puntual, pasa al siguiente nivel:
- Perfil persistente. Pasa
--user-data-dir=./chrome-profilelas cookies y que la_ddsobrevivan a las ejecuciones. - Cambia de IP tras un desafío. Un captcha en una IP residencial es recuperable; un captcha que se repite en la misma IP suele significar que está bloqueada. Cambia a una nueva salida e inténtalo de nuevo.
- Reduzca la velocidad. Introduzca un tiempo de espera aleatorio más largo (de 30 a 90 segundos) antes de volver a intentarlo tras un desafío, en lugar de bombardear la misma URL.
- Recurre a un solucionador gestionado. Cuando el rendimiento es más importante que el control, redirige la solicitud a través de una API de scraping que gestione la identificación de huellas digitales y los retos por su cuenta.
Trata el captcha como una señal de que tu huella digital, IP o ritmo han superado un umbral, no como una simple ventana emergente que hay que cerrar.
Escalar sin que te bloqueen: proxies, encabezados y control de frecuencia
Lo difícil de extraer datos de Idealista a escala de producción no es analizar el HTML, sino adelantarse a los bloqueos. Una vez que tu prototipo funciona, el escalado expone nuevos modos de fallo. Las IP de los centros de datos que sobrevivieron a tus primeras 200 solicitudes son desafiadas en masa, los encabezados idénticos en todos los trabajadores llaman la atención y las solicitudes estrechamente sincronizadas parecen un bot coordinado.
Organiza tus defensas en este orden y solo añade complejidad cuando la capa anterior deje de funcionar.
1. Proxies residenciales o móviles, con segmentación geográfica. El tráfico de Idealista está dominado por consumidores españoles, italianos y portugueses. Las IP residenciales de esos países se camuflan; un ASN de un centro de datos estadounidense no. Con selenium-wire:
from seleniumwire.undetected_chromedriver import Chrome
seleniumwire_options = {
"proxy": {
"http": "http://user:pass@es.proxy.example:8000",
"https": "http://user:pass@es.proxy.example:8000",
"no_proxy": "localhost,127.0.0.1",
}
}
driver = Chrome(seleniumwire_options=seleniumwire_options, use_subprocess=True)2. Rotación de encabezados. Alterna un pequeño conjunto de encabezados realistas de Chrome 12x (que coincidan User-Agent, sec-ch-ua, y Accept-Language). Mantén la coherencia; las pistas de cliente que no coinciden se marcan más rápido que cualquier encabezado incorrecto.
3. Límites de concurrencia. Limita los trabajadores a 1 por IP, de 4 a 8 por región y, por rastreo, a lo que admita tu plan de proxies. Añade retrasos aleatorios de 3 a 10 segundos entre las recuperaciones de páginas para que tu tráfico no sea pulsátil.
4. Una API de scraping gestionada como red de seguridad. Una vez que superes unos pocos miles de páginas al día, mantener tu propia pila de huellas digitales cuesta más de lo que ahorra. Una API de scraping gestionada se encarga de la rotación de IP, la resolución de retos y la lógica de reintentos detrás de un único punto de acceso, lo que te permite conservar tu código de análisis y simplemente cambiar la capa de obtención. Trátala como una ruta alternativa en lugar de como la opción predeterminada.
Guardar, deduplicar y exportar el conjunto de datos de propiedades extraídos
Imprimir filas en stdout está bien para una demostración, pero es inútil en producción. Escribe en el disco sobre la marcha para que un fallo a las ocho horas no borre las horas de la primera a la séptima.
import json, sqlite3
def upsert_sqlite(db_path, rows):
conn = sqlite3.connect(db_path)
conn.execute(
"CREATE TABLE IF NOT EXISTS listings ("
"id TEXT PRIMARY KEY, url TEXT, title TEXT, price TEXT, "
"details TEXT, description TEXT, scraped_at TEXT)"
)
conn.executemany(
"INSERT OR REPLACE INTO listings VALUES (?,?,?,?,?,?,datetime('now'))",
[(r["id"], r["url"], r["title"], r["price"],
json.dumps(r["details"]), r["description"]) for r in rows],
)
conn.commit(); conn.close()Utiliza el inmueble/<id> slug como clave principal; los títulos y los precios cambian, los ID no. Para flujos de trabajo más ligeros, JSONL de solo adición más una pasada diaria de deduplicación sobre la misma clave funciona bien.
Seguimiento de las propiedades de Idealista recién publicadas según un calendario
La mayoría de los equipos que preguntan cómo extraer datos de Idealista de forma periódica se preocupan menos por un volcado masivo único y más por lo que ha aparecido en las últimas 24 horas. Los agentes inmobiliarios, los fondos de inversión y las herramientas de generación de clientes potenciales quieren un delta actualizado, no el archivo completo. Idealista ofrece una clasificación por antigüedad con ?ordenado-por=fecha-publicacion-desc, que es la base para un flujo de trabajo ligero de seguimiento de cambios.
El patrón es sencillo: ejecuta el rastreador con la URL ordenada por fecha de publicación para cada municipio vigilado, compara los ID resultantes con tu última ejecución y emite solo las nuevas filas.
def diff_new_listings(rows, seen_ids_path):
seen = set(pathlib.Path(seen_ids_path).read_text().splitlines()) if pathlib.Path(seen_ids_path).exists() else set()
new_rows = [r for r in rows if r["id"] not in seen]
pathlib.Path(seen_ids_path).write_text(
"\n".join(seen | {r["id"] for r in new_rows})
)
return new_rowsPrograma la tarea cada hora mediante cron o Airflow, envía alertas sobre nuevas filas a través de Slack o correo electrónico, y tendrás un radar inmobiliario operativo sin necesidad de un backend personalizado.
Solución de problemas: resultados vacíos, selectores obsoletos y fallos de ChromeDriver
Unos pocos patrones explican la mayoría de los fallos que nos reportan los lectores.
use_subprocesspeculiaridad. Las versiones recientesundetected-chromedrivernecesitanuse_subprocess=Trueen algunas plataformas para evitar una advertencia del destructor que puede corromper el controlador. Verifícalo con el repositorio de origen, ya que la solución varía según la versión.NoSuchElementExceptionen las tarjetas. Normalmente, Idealista ha cambiado el nombre de una clase. Vuelve a inspeccionar el DOM y da preferenciacontains(@class, ...)a la igualdad estricta./en/Diferencias de diseño. La configuración regional en inglés ofrece un DOM ligeramente diferente. Fíjate en la configuración regional que realmente deseas y mantén los selectores por configuración regional si cruzas sitios.- Incompatibilidad entre Chrome y el controlador. Fija ambos. Una
SessionNotCreatedExceptioncasi siempre significa que el controlador parcheado y tu Chrome instalado difieren en una versión principal.
Conclusiones clave
- La pila de bloqueo de Idealista combina los retos de DataDome, la identificación de TLS y la reputación de IP, por lo que una única táctica como la rotación de User-Agents no será suficiente a gran escala.
- Utiliza el
inmueble/<id>slug como clave de deduplicación e identificador principal; los títulos y los precios cambian, los ID no. - Limita tu paginación (alrededor de 40 páginas por municipio) y divide las consultas más profundas por rango de precios o tipo de propiedad en lugar de recurrir indefinidamente.
- Estructura tus defensas en el siguiente orden: huella digital de navegador real, IP residenciales geolocalizadas, rotación de encabezados, ritmo de solicitud moderado y, por último, una API de scraping gestionada como plan de contingencia.
- Realiza un seguimiento de los nuevos anuncios ordenando
fecha-publicacion-descy comparando los ID con tu última ejecución; esto es lo que convierte a un scraper en un producto útil.
Preguntas frecuentes
¿Es legal el scraping de Idealista y cómo se aplica el RGPD a los datos de contacto de los agentes?
Por lo general, es legal recopilar datos de anuncios públicos a un ritmo razonable, pero los nombres, teléfonos y correos electrónicos de los agentes son datos personales según el RGPD y requieren una base legal documentada, límites de conservación y una ruta de eliminación. Almacenar o redistribuir los datos de contacto de los agentes a gran escala sin esos controles es la parte más arriesgada de cualquier proceso de Idealista. Consulta a un abogado para obtener orientación específica sobre tu jurisdicción.
¿Ofrece Idealista una API oficial para datos inmobiliarios?
Idealista no publica una API de anuncios públicos de uso general. Su programa para desarrolladores está orientado a integraciones con socios y a la colocación de anuncios, más que al acceso abierto a los datos. Para la mayoría de los casos de uso de análisis o investigación, extraer datos del sitio web público o comprar un conjunto de datos inmobiliarios gestionado son las opciones más realistas. Consulte directamente el portal de desarrolladores actual antes de dar por hecho que hay algún punto de conexión específico disponible.
¿Por qué Idealista sigue mostrando un captcha de DataDome incluso cuando utilizo undetected-chromedriver?
undetected-chromedriver solo corrige una señal, la navigator.webdriver flag y algunos aspectos internos de Chrome. DataDome también evalúa huellas TLS, coherencia de encabezados, reputación de IP y ritmo de comportamiento. Si tu IP se encuentra en un rango de centros de datos marcado, o tus encabezados son inconsistentes, el desafío seguirá activándose. Añade primero proxies residenciales y un ritmo más lento.
¿Debería usar Selenium, HTTPX con parsel o una API de scraping gestionada para Idealista?
Depende del volumen. Para unos pocos cientos de páginas, HTTPX con Parsel es lo más rápido. Para una extracción fiable por página con renderizado JS, Selenium con undetected-chromedriver es el término medio probado. A partir de unos pocos miles de páginas al día, una API de scraping gestionada elimina la sobrecarga de los proxies y la resolución de retos, y suele ser más barata que mantener tu propia pila de huellas digitales.
¿Puede el mismo scraper funcionar en los sitios web de Idealista en italiano y portugués y en los anuncios de alquiler?
En gran medida, sí. Los sitios web en italiano (idealista.it) y portugués (idealista.pt) suelen compartir el diseño del español, y los alquileres siguen un alquiler-viviendas patrón que refleja venta-viviendas. Verifica los selectores en páginas en vivo, ya que Idealista realiza ocasionalmente pruebas A/B con ajustes específicos para cada idioma en cuanto a la disposición de las tarjetas y la paginación.
Conclusión
Descubrir cómo extraer datos de Idealista es, en gran medida, un ejercicio de respetar las defensas en capas que el sitio ha construido a lo largo de los años. Consigue el mapa de URL correcto, utiliza una huella digital de navegador real con undetected-chromedriver, vincula tu paginación, elimina duplicados en el inmueble/<id> slug y escribe en disco en tiempo real para que un fallo nunca te cueste una ejecución completa. Trata los avisos de DataDome como una señal de que tu IP, huella digital o ritmo de solicitud han sobrepasado un límite, no como una ventana emergente en la que hacer clic. Una vez que pases del prototipo a la escala de producción, la estrategia por capas (proxies residenciales, geolocalización, rotación de encabezados, lógica de reintentos) empieza a amortizarse casi de inmediato.
Si prefieres saltarte por completo la configuración de proxies y la resolución de retos, la API Scraper de WebScrapingAPI se encarga de la capa de obtención detrás de un único punto final, devolviendo HTML que puedes introducir directamente en los analizadores mencionados anteriormente. En cualquier caso, el flujo de trabajo aquí te ofrece una ruta clara desde un prototipo en una sola máquina hasta un proceso programado que rastrea nuevos anuncios en español, italiano y portugués con una cadencia útil.




