Guía para el scraping de datos inmobiliarios de Zillow con Python

Comentarios: 0

Extraer información inmobiliaria de Zillow puede ofrecer un análisis perfecto para el mercado y las inversiones. Este post tiene como objetivo discutir el raspado de listados de propiedades Zillow con Python donde se especializará en los pasos esenciales que se toman y las directrices. Esta guía le mostrará cómo raspar información del sitio web de Zillow utilizando bibliotecas como requests, y lxml.

Instalación de las librerías necesarias y comienzo del scraping

Antes de empezar, asegúrate de que tienes Python instalado en tu sistema. También necesitarás instalar las siguientes librerías:

pip install requests
pip install lxml

Paso 1. Entender la estructura HTML de Zillow

Para extraer datos de Zillow, necesitas entender la estructura de la página web. Abre una página de listado de propiedades en Zillow e inspecciona los elementos que quieres raspar (por ejemplo, el título de la propiedad, el precio estimado del alquiler y el precio de tasación).

Título:

1.png

Detalles del precio:

2.png

Paso 2. Realizar peticiones HTTP

Ahora vamos a enviar peticiones HTTP. En primer lugar, necesitamos obtener el contenido HTML de la página de Zillow. Utilizaremos la librería requests para enviar una petición HTTP GET a la URL de destino. También configuraremos las cabeceras de la petición para imitar una petición real del navegador y usaremos proxies para evitar el bloqueo de IPs.

import requests

# Definir la URL de destino para el listado de propiedades de Zillow
url = "https://www.zillow.com/homedetails/1234-Main-St-Some-City-CA-90210/12345678_zpid/"

# Configure las cabeceras de la petición para imitar la petición de un navegador
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-US,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'sec-ch-ua': '"Not/A)Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
    'sec-ch-ua-mobile': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
}

# Opcionalmente, configure proxies para evitar el bloqueo de IP.
proxies = {
    'http': 'http://username:password@your_proxy_address',
    'https://username:password@your_proxy_address',
}


# Enviar la solicitud HTTP GET con cabeceras y proxies
response = requests.get(url, headers=headers, proxies=proxies)
response.raise_for_status()  # Ensure we got a valid response

Paso 3. Analizar el contenido HTML

A continuación, tenemos que analizar el contenido HTML utilizando lxml. Utilizaremos la función fromstring del módulo lxml.html para analizar el contenido HTML de la página web y convertirlo en un objeto Element.

from lxml.html import fromstring

# Analiza el contenido HTML con lxml
parser = fromstring(response.text)

Paso 4. Extracción de datos

Ahora, extraeremos puntos de datos específicos como el título de la propiedad, el precio estimado del alquiler y el precio de tasación utilizando consultas XPath en el contenido HTML analizado.

# Extracción del título de la propiedad mediante XPath
title = ' '.join(parser.xpath('//h1[@class="Text-c11n-8-99-3__sc-aiai24-0 dFxMdJ"]/text()'))

# Extracción del precio estimado del alquiler del inmueble mediante XPath
rent_estimate_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-2]

# Extracción del precio de tasación mediante XPath
assessment_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-1]

# Almacenar los datos extraídos en un diccionario
property_data = {
    'title': title,
    'Rent estimate price': rent_estimate_price,
    'Assessment price': assessment_price
}

Paso 5. Guardar los datos en JSON

Por último, guardaremos los datos extraídos en un archivo JSON para su posterior procesamiento.

import json

# Definir el nombre del archivo JSON de salida
output_file = 'zillow_properties.json'

# Abrir el fichero en modo escritura y volcar los datos
with open(output_file, 'w') as f:
    json.dump(all_properties, f, indent=4)

print(f"Scraped data saved to {output_file}")

Manejo de múltiples URL

Para scrapear múltiples listados de propiedades, iteraremos sobre una lista de URLs y repetiremos el proceso de extracción de datos para cada una de ellas.

# Lista de URL que se van a raspar
urls = [
    "https://www.zillow.com/homedetails/1234-Main-St-Some-City-CA-90210/12345678_zpid/",
    "https://www.zillow.com/homedetails/5678-Another-St-Some-City-CA-90210/87654321_zpid/"
]

# Lista para almacenar los datos de todas las propiedades
all_properties = []

for url in urls:
    # Enviar la solicitud HTTP GET con cabeceras y proxies
    response = requests.get(url, headers=headers, proxies=proxies)
    response.raise_for_status()  # Ensure we got a valid response

    # Analiza el contenido HTML con lxml
    parser = fromstring(response.text)

    # Extraer datos mediante XPath
    title = ' '.join(parser.xpath('//h1[@class="Text-c11n-8-99-3__sc-aiai24-0 dFxMdJ"]/text()'))
    rent_estimate_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-2]
    assessment_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-1]

    # Almacenar los datos extraídos en un diccionario
    property_data = {
        'title': title,
        'Rent estimate price': rent_estimate_price,
        'Assessment price': assessment_price
    }

    # Añadir los datos de la propiedad a la lista
    all_properties.append(property_data)

Código completo

Aquí está el código completo para scrapear datos de propiedades de Zillow y guardarlos en un archivo JSON:

import requests
from lxml.html import fromstring
import json

# Definir las URL de destino para los listados de propiedades de Zillow
urls = [
    "https://www.zillow.com/homedetails/1234-Main-St-Some-City-CA-90210/12345678_zpid/",
    "https://www.zillow.com/homedetails/5678-Another-St-Some-City-CA-90210/87654321_zpid/"
]

# Configure las cabeceras de la petición para imitar la petición de un navegador
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-US,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'sec-ch-ua': '"Not/A)Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
    'sec-ch-ua-mobile': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
}

# Opcionalmente, configure proxies para evitar el bloqueo de IP.
proxies = {
    'http': 'http://username:password@your_proxy_address',
    'https': 'https://username:password@your_proxy_address',
}

# Lista para almacenar los datos de todas las propiedades
all_properties = []

for url in urls:
    try:
        # Enviar la solicitud HTTP GET con cabeceras y proxies
        response = requests.get(url, headers=headers, proxies=proxies)
        response.raise_for_status()  # Ensure we got a valid response

        # Analiza el contenido HTML con lxml
        parser = fromstring(response.text)

        # Extraer datos mediante XPath
        title = ' '.join(parser.xpath('//h1[@class="Text-c11n-8-99-3__sc-aiai24-0 dFxMdJ"]/text()'))
        rent_estimate_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-2]
        assessment_price = parser.xpath('//span[@class="Text-c11n-8-99-3__sc-aiai24-0 dFhjAe"]//text()')[-1]

        # Almacenar los datos extraídos en un diccionario
        property_data = {
            'title': title,
            'Rent estimate price': rent_estimate_price,
            'Assessment price': assessment_price
        }

        # Añadir los datos de la propiedad a la lista
        all_properties.append(property_data)

    except requests.exceptions.HTTPError as e:
        print(f"HTTP error occurred: {e}")
    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")

# Definir el nombre del archivo JSON de salida
output_file = 'zillow_properties.json'

# Abrir el fichero en modo escritura y volcar los datos
with open(output_file, 'w') as f:
    json.dump(all_properties, f, indent=4)

print(f"Scraped data saved to {output_file}")

Entendiendo la estructura de las páginas HTML y aprovechando potentes librerías como requests y lxml, puedes extraer eficientemente los detalles de las propiedades. Utilizar proxies y agentes de usuario rotativos le permite realizar un gran volumen de peticiones a sitios como Zillow sin riesgo de ser bloqueado. Para estas actividades, los proxies ISP estáticos o los proxies residenciales rotativos se consideran opciones óptimas.

Comentarios:

0 Comentarios