перейти к содержанию

Как очистить данные о недвижимости Redfin на Python – полное руководство

Как инвестор в недвижимость и специалист по данным, я очарован информацией, скрывающейся в данных о листингах недвижимости. Redfin, один из крупнейших сайтов по недвижимости, который посещают более 5 миллионов человек в месяц, предлагает множество интересной информации о предложениях, которая только и ждет, чтобы ее извлекли.

В этом пошаговом руководстве вы узнаете, как я использую Python для сбора ключевых данных Redfin о недвижимости, чтобы использовать их в своих алгоритмах инвестирования в недвижимость.

К концу вы сможете создать свой собственный парсер объявлений Redfin, чтобы собирать наборы данных о ценах, тенденциях рынка жилья и многом другом. Давайте погрузимся!

Зачем очищать данные листинга Redfin?

Прежде чем мы углубимся в технические подробности, давайте обсудим зачем Возможно, вы захотите сначала очистить списки Redfin.

1. Исследования рынка

Redfin имеет более 2 миллионов активных объявлений о недвижимости в США — это огромный набор данных для анализа цен, спроса и тенденций в разных регионах. Извлечение и обработка этих данных может дать ценную информацию о рынке.

2. Исследование конкурентов

Изучение того, какие дома продали ваши конкуренты, агенты по недвижимости, и по какой цене, может дать вам преимущество в переговорах.

3. Разработка алгоритма

Собранные данные о недвижимости могут служить входными данными для автоматизированных алгоритмов оценки дома с использованием машинного обучения. Имея достаточно исторических примеров, вы можете сделать точные прогнозы цен.

4. Инструмент поиска дома

Соберите все объявления в городе, обновляемые ежедневно, чтобы создать мощный инструмент поиска недвижимости или инвестиционную панель.

Короче говоря, если вы сможете извлечь и использовать обширные данные о листинге Redfin, возможности безграничны. Теперь давайте посмотрим, как это сделать.

Обзор доступных данных листинга Redfin

Перед парсингом полезно понять, какие именно данные мы можем извлечь из Redfin. Вот некоторые из основных полей данных, доступных на типичной странице объявления:

подробности адреса

  • Полный адрес
  • Почтовый индекс
  • Район
  • Объем партии
  • Идентификатор посылки

Информация о цене

  • Текущая цена листинга
  • История цен и изменения
  • Подробности о снижении цены
  • Цена за квадратный метр

Детали:

  • Квадратные метры
  • Кол-во спален
  • Количество санузлов
  • Год постройки
  • Тип недвижимости (дом, квартира, многоквартирный дом)

Описание

  • Полное описание листинга
  • Список удобств

Фотографии и виртуальный тур

  • Фотографии основного объявления
  • Дополнительные фотографии окрестностей
  • 3D-сканирование (если доступно)
  • Фотографии с дрона (если есть)

Информация об агенте

  • Подробности листингового агента
  • Фото агента
  • Детали офиса
  • Профиль агента и контактная информация

Интерактивные карты

  • Очертания границ
  • Формы школьного округа
  • Слои времени в пути
  • Информация о районе

И многое другое ...

Как видите, каждый листинг Redfin содержит кладезь данных. Теперь давайте посмотрим, как мы можем его извлечь.

Парсинг страницы листинга Redfin

Есть несколько подходов к очистке листинга Redfin:

  • Разобрать отрендеренный HTML - Грязный и склонный к поломке
  • Извлечь необработанные данные JSON – Метод будущего

Я настоятельно рекомендую очистить JSON. Redfin использует React для рендеринга страниц списков, асинхронно загружая данные из внутренних API JSON.

Мы можем имитировать браузер и получать эти данные напрямую. Вот фрагмент кода Python для извлечения необработанного списка JSON:

import requests
import re
import json

listing_url = "https://www.redfin.com/CA/San-Francisco/123-Main-St-94104/home/123456"

response = requests.get(listing_url)

match = re.search(r‘window.__data__ = (.+);‘, response.text)
json_data = json.loads(match.group(1))

print(json_data.keys())

Это позволяет получить полную информацию о листинге на странице Redfin. Гораздо проще, чем анализировать обработанный HTML!

Структура JSON является вложенной и содержит каждый отображаемый фрагмент данных. Давайте посмотрим, как разобрать его на что-то более полезное.

Анализ полей данных списка ключей

Необработанный листинг JSON содержит массу ненужных технических метаданных. Мы хотим извлечь только самое важное.

Вот пример парсера для извлечения полей в чистый словарь Python:

def parse_listing(data):

  return {
    "price": data["homeDetails"]["price"],
    "address": data["homeDetails"]["address"]["line1"],
    "beds": data["homeDetails"]["beds"],
    "baths": data["homeDetails"]["baths"],
    "sqft": data["homeDetails"]["sqft"],
    "built": data["homeDetails"]["yearBuilt"],
    "desc": data["homeDetails"]["description"],
    "photos": [p["highResPath"] for p in data["homeDetails"]["photos"]],
  }

data = parse_listing(json_data)
print(data)

С помощью простого обхода JSON мы можем извлечь ключевые поля в удобные форматы.

Теперь предостережение… хотя вышеописанное работает, структуры JSON могут неожиданно измениться, что приведет к поломке скребков. Лучшая практика — обернуть логику синтаксического анализа в блоки try/кроме, чтобы корректно обрабатывать любые изменения полей, которые может внести Redfin.

Это гарантирует, что ваш скребок продолжит работать, а не разобьется.

Поиск страниц с листингом Redfin для очистки

Хорошо, мы можем парсить отдельные страницы объявлений… но как нам найти листинги и загрузить их в наш парсер?

Redfin предлагает несколько вариантов поиска URL-адресов листинга:

Поиск страницы

Имитируйте поиск на веб-сайте Redfin, разбивая страницы путем настройки page Параметр:

https://www.redfin.com/city/37449/CA/San-Francisco/filter/property-type=house,max-price=1.5M,page=2

Плюсы:

  • Зеркальный опыт поиска пользователей

Минусы:

  • Легко заблокироваться при агрессивном соскабливании
  • Трудно разбить все списки на страницы.

Файлы Sitemap для местоположений

Redfin предоставляет подробные карты сайта, разделяющие списки по городам, округам, районам, почтовым индексам и т. д.

Например:

https://www.redfin.com/sitemap-location-CA-San-Francisco-buy.xml
https://www.redfin.com/sitemap-neighborhood-CA-San-Francisco-Mission-District-buy.xml 

Плюсы:

  • Структурированный формат карты сайта
  • Детально сегментировать списки

Минусы:

  • Файлы Sitemap необходимо обнаруживать вручную.

Новейшие/последние файлы Sitemap

Специальные карты сайта предоставляют новые объекты недвижимости, а также недавние обновления объявлений:

https://www.redfin.com/newest_listings.xml
https://www.redfin.com/updated_listings.xml

Плюсы:

  • Получайте свежие данные по мере их появления

Минусы:

  • Только новые или обновленные объявления

Сканирование связанных списков

В каждом объявлении есть «Похожие дома», которые мы можем рекурсивно сканировать:

похожие дома

Плюсы:

  • Развернуть до похожих объявлений

Минусы:

  • Легко сканировать несвязанные дома

Я рекомендую комбинировать карты сайта для расширения и сканирования для глубины.

Теперь давайте посмотрим на постоянный сбор самых свежих списков.

Отслеживание новых и обновленных данных о листинге

Хотя сбор исторических данных о листингах полезен, в идеале нам нужны новые и обновленные листинги, поскольку они поддерживают актуальность нашего набора данных.

Redfin предоставляет для этого две ключевые карты сайта:

Новейшая карта сайта

В этом канале перечислены недавно опубликованные объявления с отметкой времени публикации:

<url>
  <loc>https://www.redfin.com/CA/San-Francisco/456-Park-St-94102/home/4567123</loc>
  <lastmod>2023-03-01T22:10:35Z</lastmod>
</url>

Последняя карта сайта

Последние индексы карты сайта за последнее время обновление списки:

<url>
  <loc>https://www.redfin.com/CA/San-Francisco/123-Main-St-94104/home/123456</loc>
  <lastmod>2023-03-01T22:18:26Z</lastmod>
</url>

Вот пример кода Python для непрерывного очистки этих карт сайта:

import requests
from lxml import etree
from datetime import datetime

INIT_TIME = datetime(2023, 2, 1) # initial run

def scrape_sitemaps():

  newest_url = "https://www.redfin.com/newest_listings.xml"
  latest_url = "https://www.redfin.com/latest_listings.xml"

  new_listings = []

  # fetch newest sitemap and parse listings
  response = requests.get(newest_url)
  dom = etree.XML(response.content)
  for url_el in dom.xpath("//url"):
    name = url_el.find("loc").text
    published = url_el.find("lastmod").text
    published_dt = datetime.strptime(published, "%Y-%m-%dT%H:%M:%S.%fZ")
    # filter only new listings since initial run
    if published_dt > INIT_TIME:
      new_listings.append(name)

  # same process for latest sitemap
  response = requests.get(latest_url)
  dom = etree.XML(response.content)
  for url_el in dom.xpath("//url"):
   name = url_el.find("loc").text
   updated = url_el.find("lastmod").text
   updated_dt = datetime.strptime(updated, "%Y-%m-%dT%H:%M:%S.%fZ")
   if updated_dt > INIT_TIME and name not in new_listings:
      new_listings.append(name)

  # scrape new listings...
  for url in new_listings:
    data = scrape_listing(url) 
    print("Scraped new listing:", url)
    # save listings to database...

Запланировав запуск каждый час, вы сможете получать самые свежие данные о недвижимости.

Теперь давайте посмотрим, как парсить листинги Redfin в больших масштабах, не подвергаясь блокировке.

Как избежать масштабных блоков с помощью прокси

Хотя наши парсеры работают нормально, извлекая несколько списков, агрессивный парсер, скорее всего, приведет к блокировке.

Redfin использует расширенную защиту от ботов и мониторинг предотвращения злоупотреблений, чтобы предотвратить крупномасштабный парсинг.

Для безопасного парсинга в больших масштабах нам нужны прокси. Прокси предоставляют новые IP-адреса для маршрутизации каждого запроса, распределяя нагрузку и избегая шаблонов.

Существует два распространенных подхода:

1. Жилые прокси

Использование прокси-IP-адресов от домашних интернет-провайдеров, таких как Comcast или Verizon, имитирует реальных домашних пользователей, что делает вас менее подозрительными.

2. Прокси для центров обработки данных

Прокси-серверы от облачных провайдеров, таких как Amazon AWS и Google Cloud, сочетаются с обычным веб-трафиком.

Я рекомендую сочетание обоих типов прокси для оптимальной производительности и предотвращения блокировок.

Давайте рассмотрим пример с использованием API прокси BrightData:

from brightdata.sdk import BrightData

proxy = BrightData("YOUR_API_KEY")

urls = [# list of URLs to scrape...
]

for url in urls:

  with proxy.browser(residential=True) as browser:
    browser.get(url)
    html = browser.page_source
    # parse listing data from HTML...

  with proxy.browser(datacenter=True) as browser:
    browser.get(url)
    html = browser.page_source
    # parse listing data from HTML... 

API обрабатывает ротацию прокси при каждом запросе, позволяя нам сосредоточиться на извлечении данных.

Используя правильное прокси-решение, вы можете очищать списки Redfin в большом масштабе без сбоев.

Парсинг списков Redfin: следующие шаги

В этом руководстве мы рассмотрели массу вопросов! Напомним ключевые моменты:

  • Redfin предоставляет множество данных о листингах недвижимости
  • Мы можем извлекать данные JSON вместо анализа HTML.
  • Существует несколько методов поиска списков для парсинга.
  • Отслеживание новейших/последних файлов Sitemap позволяет выявить свежие списки.
  • Прокси помогают избежать блоков при парсинге в больших масштабах.

Примеры кода предоставляют шаблон — с дополнительной обработкой ошибок и уточнениями вы можете создать надежный парсер списков Redfin.

Возможные следующие шаги включают в себя:

  • Хранение данных в базе данных SQL или NoSQL.
  • Создание собственного API для обслуживания агрегированных данных о листинге
  • Анализ данных для получения информации о ценах, спросе и многом другом.
  • Создание инструмента или панели управления недвижимостью поверх собранных списков

Возможности безграничны, как только вы разблокируете данные Redfin в большом масштабе. Просто обязательно соблюдайте этические правила очистки и соблюдайте разумные ограничения на использование.

Я надеюсь, что это руководство станет надежной отправной точкой для ваших собственных проектов парсинга Redfin. Бросайте!

Теги:

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *