Guía para hacer web scraping de datos de precios reales de bienes raíces - Recopilación automática de precios de apartamentos y oficinas.

Guía sobre cómo recopilar datos de precios reales de bienes raíces, incluyendo métodos como API pública, web scraping y servicios especializados. Datos oficiales del Ministerio de Tierras, Infraestructura y Transporte, información de Naver Real Estate, Zigbang y Korea Real Estate Information.

12
Guía para hacer web scraping de datos de precios reales de bienes raíces - Recopilación automática de precios de apartamentos y oficinas.

"Este apartamento, ¿debería comprarlo ahora?"

Para responder a esta pregunta, al final se necesita datos. Tendrás que evaluar los datos en lugar de confiar en tu intuición: tendencias de precios reales, precios en la zona, tasa de alquiler mensual, cambios en el volumen de transacciones, etc. Todos, desde inversores inmobiliarios hasta startups de PropTech, agencias inmobiliarias y académicos, se enfrentan a la misma pregunta: "¿Cómo podemos recopilar estos datos automáticamente?"

En este artículo se abordan tres formas de recopilar datos de precios reales de propiedades:

  1. API pública — API de precios reales del Ministerio de Tierras, Infraestructura y Transporte (gratuita, la más segura)
  2. Rastreo directo — Rastreo de sitios web como Naver Real Estate (alto nivel de dificultad técnica)
  3. Servicios especializados — Recopilación automática utilizando servicios de rastreo (más conveniente)

Se detallan las ventajas y desventajas de cada método, se proporciona código práctico en Python, se abordan problemas comunes y se mencionan consideraciones legales.


Índice

  1. ¿Dónde se encuentran los datos inmobiliarios?
  2. Método 1: Utilización de la API pública del Ministerio de Tierras, Infraestructura y Transporte
  3. Método 2: Rastreo de Naver Real Estate
  4. Método 3: Utilización de servicios de rastreo especializados
  5. Utilización de los datos recopilados — Análisis y visualización
  6. Solución de problemas comunes — Problemas frecuentes y sus soluciones
  7. Consideraciones legales
  8. Preguntas frecuentes (FAQ)

¿Dónde se encuentran los datos inmobiliarios?

Los datos de transacciones inmobiliarias en Corea del Sur se proporcionan desde múltiples fuentes, y la fuente adecuada varía según el propósito.

1. Sistema de precios reales del Ministerio de Tierras, Infraestructura y Transporte

URL: rt.molit.go.kr

Estos son los datos oficiales de precios reales operados por el Ministerio de Tierras, Infraestructura y Transporte. Cuando se informa una transacción inmobiliaria, se hace pública en este sistema.

Datos proporcionados:
- Compra y alquiler mensual de apartamentos, casas adosadas/dúplex, viviendas unifamiliares/multifamiliares
- Compra y alquiler mensual de estudios
- Transacciones de terrenos, derechos de desarrollo/ocupación, propiedades comerciales/de negocios
- Fecha de transacción, monto de la transacción, área, número de pisos, año de construcción, etc.

API de Portal de Datos Públicos:
En Data.go.kr puedes utilizar la API de precios reales del Ministerio de Tierras, Infraestructura y Transporte de forma gratuita. Una vez obtengas la clave de la API, puedes recopilar datos automáticamente mediante programación.

Ventajas: Datos oficiales, gratuitos, sin riesgos legales
Desventajas: Solo se proporcionan precios reales (sin información sobre precios de mercado o propiedades), actualización retrasada

2. Naver Real Estate

URL: land.naver.com

Además de los datos de precios reales, Naver Real Estate proporciona la información más rica en detalles, como información sobre propiedades en venta, precios de mercado, escuelas, infraestructura circundante, etc.

Datos proporcionados:
- Precios reales (basados en datos del Ministerio de Tierras, Infraestructura y Transporte)
- Información actual de propiedades en venta (precio de venta, tipo de propiedad)
- Información de precios de mercado (precio estimado por KB, precio estimado por Naver)
- Información de complejos residenciales (número de unidades, estacionamiento, gastos de administración, etc.)
- Información sobre escuelas y servicios cercanos

Ventajas: Datos detallados, fácil de usar
Desventajas: Alto nivel de dificultad para rastrear, restricciones en los términos de uso

3. Zigbang / Dabang

URL: zigbang.com / dabangapp.com

Estas plataformas tienen ventajas en la información de propiedades, especialmente en propiedades más pequeñas y enfocadas en alquileres mensuales. Especialmente tienen datos abundantes sobre el mercado de alquileres mensuales.

Ventajas: Datos abundantes sobre propiedades más pequeñas/alquileres mensuales
Desventajas: Menos datos sobre transacciones de apartamentos en comparación con Naver Real Estate

4. Korea Real Estate Institute (anteriormente Korea Appraisal Board)

URL: reb.or.kr

Proporciona datos estadísticos sobre tendencias de precios inmobiliarios, tasa de conversión de alquileres mensuales a ventas, índices de precios de venta/alquiler, etc. Puedes acceder a una variedad de estadísticas a través del sistema de información estadística inmobiliaria R-ONE.

Ventajas: Estadísticas oficiales, proporciona índices de precios
Desventajas: Datos agregados en lugar de datos de transacciones individuales


Método 1: Utilización de la API pública del Ministerio de Tierras, Infraestructura y Transporte

Este es el método más convencional y estable. Es seguro ya que se trata de datos públicos.

Paso 1: Obtener la clave de la API

  1. Regístrate en el Portal de Datos Públicos
  2. Busca "Datos de transacciones de apartamentos del Ministerio de Tierras, Infraestructura y Transporte"
  3. Haz clic en "Solicitud de uso" → Ingresa el propósito de uso
  4. Obtén la clave de la API (generalmente tarda de inmediato a 1 día)

Consejo: Se emiten dos tipos de claves de API: codificada (Encoding) y decodificada (Decoding). Es conveniente utilizar la clave decodificada en Python. Si utilizas la clave codificada, es posible que ocurran errores al realizar una doble codificación con la biblioteca requests.

Lista de API principales

Nombre de la API Descripción Código de servicio
Datos de transacciones de apartamentos Precios de transacciones de apartamentos getRTMSDataSvcAptTrade
Datos de alquiler de apartamentos Precios de alquiler de apartamentos getRTMSDataSvcAptRent
Datos de transacciones de viviendas adosadas/multifamiliares Precios de venta de villas/dúplex getRTMSDataSvcRHTrade
Datos de transacciones de oficinas Precios de venta de oficinas getRTMSDataSvcOffiTrade
Datos de transacciones de viviendas unifamiliares/dúplex Precios de venta de viviendas unifamiliares getRTMSDataSvcSHTrade
Datos de transacciones de terrenos Precios de transacciones de terrenos getRTMSDataSvcLandTrade

Código Python — Consulta de precios de transacciones de apartamentos

import requests
import xml.etree.ElementTree as ET
import pandas as pd

# API 설정 — 디코딩된 키를 사용하세요
SERVICE_KEY = "발급받은_디코딩_API_키"
BASE_URL = "http://openapi.molit.go.kr/OpenAPI_ToolInstall/service/rest/RTMSOBJSvc/getRTMSDataSvcAptTrade"

def get_apt_trade(lawd_cd: str, deal_ymd: str) -> pd.DataFrame:
    """
    아파트 매매 실거래가를 조회합니다.

    Args:
        lawd_cd: 법정동 앞 5자리 코드 (예: "11680" = 서울 강남구)
        deal_ymd: 계약년월 (예: "202601")

    Returns:
        거래 데이터가 담긴 DataFrame
    """
    params = {
        "serviceKey": SERVICE_KEY,
        "LAWD_CD": lawd_cd,
        "DEAL_YMD": deal_ymd,
        "numOfRows": "9999",
        "pageNo": "1"
    }

    response = requests.get(BASE_URL, params=params, timeout=30)
    response.raise_for_status()

    root = ET.fromstring(response.text)

    # 에러 체크
    result_code = root.find(".//resultCode")
    if result_code is not None and result_code.text != "00":
        result_msg = root.find(".//resultMsg")
        raise Exception(f"API 오류: {result_msg.text if result_msg is not None else 'Unknown'}")

    items = root.findall(".//item")
    if not items:
        return pd.DataFrame()

    data = []
    for item in items:
        row = {}
        for child in item:
            text = child.text.strip() if child.text else ""
            row[child.tag] = text
        data.append(row)

    return pd.DataFrame(data)


# 사용 예시: 서울 강남구(11680) 2026년 1월 거래 조회
df = get_apt_trade("11680", "202601")
print(f"조회된 거래 수: {len(df)}")
if not df.empty:
    # 거래금액 정수 변환 (쉼표와 공백 제거)
    df["거래금액_만원"] = df["거래금액"].str.replace(",", "").str.strip().astype(int)
    print(df[["거래금액_만원", "아파트", "전용면적", ""]].head(10))

Recopilación de datos anuales para todos los distritos de Seúl

import time

# 서울시 구별 법정동 앞 5자리 코드
SEOUL_CODES = {
    "강남구": "11680", "서초구": "11650", "송파구": "11710",
    "강동구": "11740", "마포구": "11440", "용산구": "11170",
    "성동구": "11200", "광진구": "11215", "중구": "11140",
    "종로구": "11110", "영등포구": "11560", "동작구": "11590",
    "관악구": "11620", "강서구": "11500", "양천구": "11470",
    "구로구": "11530", "금천구": "11545", "노원구": "11350",
    "도봉구": "11320", "강북구": "11305", "성북구": "11290",
    "동대문구": "11230", "중랑구": "11260", "은평구": "11380",
    "서대문구": "11410"
}

def collect_seoul_yearly(year: int) -> pd.DataFrame:
    """서울시 전체 구의 1년치 아파트 매매 데이터를 수집합니다."""
    all_data = []
    months = [f"{year}{m:02d}" for m in range(1, 13)]
    total = len(SEOUL_CODES) * len(months)
    count = 0

    for gu_name, code in SEOUL_CODES.items():
        for month in months:
            count += 1
            try:
                df = get_apt_trade(code, month)
                if not df.empty:
                    df[""] = gu_name
                    all_data.append(df)
                print(f"[{count}/{total}]  {gu_name} {month}: {len(df)}")
            except Exception as e:
                print(f"[{count}/{total}]  {gu_name} {month}: {e}")
            time.sleep(0.3)  # API 호출 간격

    if all_data:
        result = pd.concat(all_data, ignore_index=True)
        return result
    return pd.DataFrame()

# 2025년 전체 데이터 수집
result = collect_seoul_yearly(2025)
result.to_csv("서울_아파트_실거래가_2025.csv", index=False, encoding="utf-8-sig")
print(f"\n{len(result)}건 수집 완료!")

Limitaciones de la API pública

Aunque la API pública es estable, tiene ciertas limitaciones:

Límite Descripción
Alcance de los datos Solo se proporcionan precios de transacciones y datos básicos. No hay información adicional como precios de mercado, propiedades en venta, etc.
Actualización retrasada No es en tiempo real, sino que se refleja días o semanas después de la presentación
Límite de llamadas Límite diario de llamadas a la API (generalmente 1,000 llamadas/día, ampliable mediante solicitud)
Formato de datos La respuesta es en formato XML de forma predeterminada (algunas API admiten JSON)
Código de área Debes gestionar por separado el código de área legal
Cambio de URL de la API La URL de la API del Portal de Datos Públicos cambia ocasionalmente

Método 2: Rastreo de Naver Real Estate

Cuando se necesitan datos más detallados que los proporcionados por la API pública, se puede considerar el rastreo de Naver Real Estate. Permite recopilar datos que la API pública no proporciona, como precios de mercado, información sobre propiedades, etc.

API interna de Naver Real Estate

Naver Real Estate llama a una API interna desde el frontend para renderizar los datos. Puedes verificar estas llamadas API en las herramientas de desarrollo del navegador (F12 → Pestaña Network).

Principales puntos finales (sujetos a cambios):

# 단지 기본 정보
GET https://fin.land.naver.com/complexes/{complexNo}

# 단지 매물 목록
GET https://fin.land.naver.com/complexes/{complexNo}/articles

# 단지 실거래가
GET https://fin.land.naver.com/complexes/{complexNo}/real-estates/trades

# 지역별 단지 목록
GET https://fin.land.naver.com/front-api/v1/complex/marker

Ejemplo de código Python — Información de complejos residenciales de Naver Real Estate

import requests
import json
import time

def get_naver_complex(complex_no: str) -> dict | None:
    """
    네이버 부동산에서 아파트 단지 정보를 조회합니다.

    주의: 네이버 내부 API는 수시로 변경될 수 있습니다.
    이 코드가 동작하지 않으면 브라우저 개발자 도구에서
    최신 API 엔드포인트를 확인하세요.
    """
    url = f"https://fin.land.naver.com/complexes/{complex_no}"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                       "AppleWebKit/537.36 (KHTML, like Gecko) "
                       "Chrome/120.0.0.0 Safari/537.36",
        "Referer": "https://land.naver.com/",
        "Accept": "application/json"
    }

    try:
        response = requests.get(url, headers=headers, timeout=10)
        if response.status_code == 200:
            return response.json()
        else:
            print(f"HTTP {response.status_code}: {complex_no}")
            return None
    except requests.exceptions.JSONDecodeError:
        # HTML이 반환된 경우 (API 변경 가능성)
        print(f"JSON 파싱 실패 — API 엔드포인트가 변경되었을 수 있습니다")
        return None
    except requests.exceptions.RequestException as e:
        print(f"요청 실패: {e}")
        return None

Problemas prácticos al rastrear

Aunque el rastreo de Naver Real Estate es teóricamente sencillo, en la práctica requiere un mantenimiento continuo:

  1. Cambio de punto final de la API: Naver cambia frecuentemente las URL de la API interna. Un código que funcionaba ayer podría fallar hoy.
  2. Token de autenticación: Algunos datos requieren un token de sesión o autenticación adicional, lo que significa que debes implementar la lógica de renovación del token.
  3. Bloqueo de IP: Si envías demasiadas solicitudes en poco tiempo, tu IP puede ser bloqueada. Es posible que necesites rotación de proxy.
  4. Renderizado de JavaScript: Algunas páginas utilizan renderizado del lado del cliente en lugar de renderizado del lado del servidor, por lo que necesitarás herramientas de automatización del navegador como Selenium o Playwright.
  5. Términos de uso: Los términos de uso de Naver prohíben la recopilación automatizada de datos. Consulta un artículo separado para obtener más información sobre problemas legales de rastreo.

Método 3: Utilización de servicios de rastreo especializados

Si deseas superar las limitaciones de la API pública y evitar la carga de mantenimiento del rastreo directo, utilizar un servicio de rastreo especializado es una opción práctica.

Comparación de tres métodos

Elemento API pública Rastreo directo Servicio especializado
Configuración inicial Días Semanas a meses Inmediato
Alcance de los datos Solo precios de transacciones Información de precios y propiedades Información de precios y propiedades
Mantenimiento Casi nulo Mucho (adaptación a cambios de API) Administrado por el servicio
Riesgos legales Ninguno Presente Administrado por el servicio
Costo Gratuito Costo de desarrollo/operación Tarifa de uso del servicio
Riesgo de bloqueo de IP Ninguno Alto Ninguno
Calidad de los datos Alta (datos oficiales) Variable Alta
Escalabilidad Limitada Implementación directa necesaria Alta

Recopilación de datos inmobiliarios con Hashscraper

Hashscraper tiene una amplia experiencia en la recopilación de datos relacionados con propiedades inmobiliarias:

  • Datos de Naver Real Estate: Recopilación automática de listados de propiedades por región/tipo, precios, área, pisos, información del complejo, etc.
  • Recopilación integrada de precios reales: Proporciona llamadas complejas de API pública a través de una interfaz simple
  • Monitoreo de cambios de precios: Rastrea periódicamente los cambios de precios y proporciona alertas
  • Integración con Excel/API: Descarga los datos recopilados en Excel o integra los datos a través de una API REST en tu sistema existente

Al construir tu propio rastreador, tendrás que dedicar tiempo a adaptarte a los cambios de API, manejar el bloqueo de IP y limpiar los datos constantemente, mientras que al utilizar un servicio especializado, puedes centrarte solo en el análisis de datos.

Si deseas obtener más información sobre la recopilación de datos inmobiliarios, puedes solicitar una consulta gratuita a través de Hashscraper.


Utilización de los datos recopilados — Análisis y visualización

Una vez que hayas recopilado los datos, es hora de extraer valor a través del análisis.

Análisis básico: Tendencias de precios por distrito

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

# 한글 폰트 설정
matplotlib.rcParams['font.family'] = 'AppleGothic'  # macOS
# matplotlib.rcParams['font.family'] = 'Malgun Gothic'  # Windows
matplotlib.rcParams['axes.unicode_minus'] = False

# 데이터 로드 및 전처리
df = pd.read_csv("서울_아파트_실거래가_2025.csv")
df["거래금액_만원"] = (
    df["거래금액"].astype(str).str.replace(",", "").str.strip().astype(int)
)
df["거래월"] = df[""].astype(str) + "-" + df[""].astype(str).str.zfill(2)

# 구별 월평균 매매가
monthly = df.groupby(["", "거래월"])["거래금액_만원"].mean().reset_index()

# 강남 3구 비교 그래프
fig, ax = plt.subplots(figsize=(12, 6))
for gu in ["강남구", "서초구", "송파구"]:
    data = monthly[monthly[""] == gu].sort_values("거래월")
    ax.plot(data["거래월"], data["거래금액_만원"] / 10000, marker="o", label=gu)

ax.set_title("강남 3구 아파트 평균 매매가 추이 (2025)", fontsize=14)
ax.set_xlabel("거래월")
ax.set_ylabel("평균 매매가 (억 원)")
ax.legend()
ax.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig("강남3구_매매가_추이.png", dpi=150)
plt.show()

Análisis avanzado: Cálculo de la tasa de alquiler mensual

La tasa de alquiler mensual (alquiler mensual ÷ precio de venta × 100) es un indicador clave en la inversión inmobiliaria. Cuanto más alta sea la tasa de alquiler mensual, más atractiva será la inversión de brecha, y cuanto más baja sea, mayor será la posibilidad de que el mercado de compra esté sobrecalentado.

def analyze_jeonse_rate(trade_file: str, rent_file: str, gu: str) -> pd.DataFrame:
    """
    특정 구의 아파트별 전세가율을 계산합니다.
    전세가율 = 전세 보증금 / 매매가 × 100
    """
    trade = pd.read_csv(trade_file)
    rent = pd.read_csv(rent_file)

    # 해당 구 필터링
    trade = trade[trade[""] == gu].copy()
    rent = rent[rent[""] == gu].copy()

    # 금액 정수 변환
    trade["매매가"] = trade["거래금액"].astype(str).str.replace(",", "").str.strip().astype(int)
    rent["보증금"] = rent["보증금액"].astype(str).str.replace(",", "").str.strip().astype(int)

    # 전세만 필터링 (월세 제외: 월세금액이 0인 경우)
    rent = rent[rent["월세금액"].astype(str).str.strip().replace("", "0").astype(int) == 0]

    # 아파트별 평균가
    avg_trade = trade.groupby("아파트")["매매가"].mean()
    avg_rent = rent.groupby("아파트")["보증금"].mean()

    # 전세가율 계산
    common = avg_trade.index.intersection(avg_rent.index)
    rates = pd.DataFrame({
        "아파트": common,
        "평균매매가_만원": avg_trade[common].values,
        "평균전세가_만원": avg_rent[common].values,
    })
    rates["전세가율"] = (rates["평균전세가_만원"] / rates["평균매매가_만원"] * 100).round(1)
    rates = rates.sort_values("전세가율", ascending=False)

    return rates

# 강남구 전세가율 분석
rates = analyze_jeonse_rate(
    "서울_아파트_매매_2025.csv",
    "서울_아파트_전세_2025.csv",
    "강남구"
)
print(rates.head(20))

Casos de uso de los datos

Usuario Propósito Datos necesarios
Inversor individual Determinar el momento de compra, seleccionar la ubicación de la inversión Tendencias de precios reales, tasa de alquiler mensual, volumen de transacciones
Startup de PropTech Modelo de predicción de precios, evaluación automática de precios Grandes volúmenes de precios reales, precios de mercado, información del complejo
Agencia inmobiliaria Comparar propiedades, material de consulta para clientes Propiedades actuales, precios reales, precios de mercado
Investigación académica Análisis de los factores que determinan los precios de las viviendas Precios reales + datos demográficos/económicos
Institución financiera Evaluación de garantías, gestión de riesgos Precios de mercado, precios reales, índices de precios

Solución de problemas comunes — Problemas frecuentes y sus soluciones

Relacionados con la API pública

Problema 1: Error "SERVICE_KEY_IS_NOT_REGISTERED_ERROR"
→ Es posible que hayas utilizado la clave codificada y requests la haya codificado nuevamente. Utiliza la clave decodificada.

Problema 2: Error "LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS_ERROR"
→ Has excedido el límite diario de llamadas. Solicita un aumento de tráfico en el Portal de Datos Públicos o intenta nuevamente al día siguiente.

Problema 3: Los datos se devuelven como 0 registros
→ Verifica si el código de área (LAWD_CD) es correcto. Utiliza solo los primeros 5 dígitos del código de área legal. Además, puede que no haya transacciones en ese mes en particular.

Problema 4: Cambio en la URL de la API
→ Verifica la página detallada de la API en el Portal de Datos Públicos. La estructura de la URL puede cambiar periódicamente. La forma más precisa es verificar la sección "Dirección solicitada (Endpoint)" de la página de la API.

Relacionados con el rastreo de Naver Real Estate

Problema 1: Respuesta "403 Forbidden"
→ Es posible que falte el encabezado User-Agent o que tu IP esté bloqueada. Configura el encabezado adecuado y aumenta el intervalo entre las solicitudes.

**Proble

Comments

Add Comment

Your email won't be published and will only be used for reply notifications.

Sigue leyendo

Get notified of new posts

We'll email you when 해시스크래퍼 기술 블로그 publishes new content.

Your email will only be used for new post notifications.