Как собрать данные с Redfin на Python и не попасть под блокировку

Последнее обновление: July 9, 2026
Как собрать данные с Redfin на Python и не попасть под блокировку

Redfin обновляет 70% новых объявлений MLS в США в течение пяти минут после их появления в системе. Такая скорость — просто находка для тех, кто строит аналитический пайплайн по недвижимости, и именно поэтому столько парсеров бросаются на Redfin и вылетают в бан буквально за минуты.

Я много лет работаю с инструментами извлечения данных в Thunderbit, и могу честно сказать: разрыв между «собрать данные с Redfin» и «собрать данные с Redfin без блокировки» — это именно то место, где ломается большинство туториалов. Вам показывают код на BeautifulSoup, пропускают часть, где Cloudflare безжалостно режет запросы, и оставляют вас смотреть на страницу 403 в полном ступоре. Это руководство другое. Я разберу три рабочих подхода — разбор HTML, скрытый API Redfin и no-code вариант с Thunderbit — и отдельно остановлюсь на антибот-защите, которая действительно имеет значение. К концу статьи вы точно поймёте, какой способ подходит под ваш уровень, масштаб и терпимость к боли при поддержке.

Попробовать Thunderbit для сбора данных с Redfin

Что такое Redfin и почему его данные так важны?

Redfin — это технологичная риелторская платформа с агентами на зарплате, которые получают объявления напрямую из лент MLS. Сервис охватывает более 100 городских агломераций США и Канады в 42 штатах и привлекает почти 50 миллионов посетителей в месяц. В отличие от порталов-агрегаторов, данные Redfin проходят проверку агентами, а собственная модель Redfin Estimate AVM охватывает более 95 миллионов объектов со средней ошибкой всего 1,96% для объектов, находящихся в продаже.

redfin_stats_f3c7fb5cbd.png

Именно сочетание свежести уровня MLS, качества с проверкой брокером и точной AVM-модели делает данные Redfin такими ценными для инвесторов в недвижимость, агентов, proptech-стартапов и аналитиков. Python здесь — естественный выбор: экосистема для парсинга (requests, BeautifulSoup, Selenium, Playwright) давно зрелая, сообщество огромное, а сам код легко связывается с pandas и Jupyter для анализа.

Зачем собирать данные Redfin на Python?

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

АудиторияОсновная цель сбораПример сценария
РиелторыГенерация лидов, рыночная аналитикаНовые и истёкшие объявления в зоне обслуживания; каталог агентов для сравнения с конкурентами
Инвесторы в недвижимостьПоиск сделок, анализ cap rateПроверка доходности аренды, выявление недооценённых объектов, ежедневные уведомления о новых объявлениях
Proptech-стартапыПотоки данных для продуктаДанные для обучения AVM, рыночные дашборды, движки покупки для iBuyer
Аналитики данныхИсследования рынка, BIТренды медианной цены по ZIP-кодам, временные ряды по дням на рынке, соотношение цены продажи к цене листинга
Оптовики / флипперыОтслеживание проблемных объектовВыявление снижения цен, foreclosure, сравнение off-market объектов

Более широкий тренд это подтверждает: более 72% компаний в сфере недвижимости уже используют предиктивную аналитику для поиска возможностей и управления рисками. Рынок PropTech, по прогнозам, достигнет $47 млрд в 2025 году при CAGR 16,4%. Структурированные данные по недвижимости уже не «приятный бонус» — это базовая необходимость.

Все поля Redfin, которые можно собрать (полный справочник)

Прежде чем писать хоть строчку кода, нужно понимать, какие именно данные доступны. Я изучил страницы результатов поиска Redfin, страницы объектов и профили агентов — и сверил их с open-source обёртками Stingray API вроде проектов reteps/redfin и RedfinPlus. В сумме получилось 117 отдельных полей по разным типам страниц.

Эту таблицу лучше сохранить в закладки. Понимание схемы данных до начала разработки экономит часы на поиске селекторов методом проб и ошибок.

Поля страницы результатов поиска

Это компактные поля, доступные на карточках объектов — их часто можно вытащить без полной JavaScript-рендеринга:

ПолеТип данныхПримечания
ID объектаЧислоВнутренний int Redfin, парсится из /home/{id} в href
Цена листингаЧисло
Полный адресТекст
Спальни / ванные / площадьЧислоТри значения подряд
Тип недвижимостиSingle SelectSFH, Condo, Townhouse, Multi
СтатусТекстActive, Pending, Contingent
Дней на рынкеЧисло
Индикатор снижения ценыЧислоРазница от первоначальной цены
Главное фотоURL изображенияПо одному фото на карточку
Бейдж Hot HomeBoolean
Дата/время open houseТекст
Атрибуция брокераТекст

Поля страницы объекта

На странице объекта скрыта настоящая глубина данных. Многие из этих полей требуют JavaScript-рендеринга или Stingray API:

ПолеТип данныхПримечания
Redfin Estimate (для объекта в продаже)ЧислоЧерез /stingray/api/home/details/avm
Redfin Estimate (для объекта вне рынка)ЧислоЧерез /stingray/api/home/details/owner-estimate; медианная ошибка 7,52%
Год постройки / реновацииЧисло
Размер участкаЧисло
HOA duesЧислоЕжемесячно, если применимо
Налог на недвижимость (в год)Число
Оценочная налоговая стоимостьЧисло
Таблица истории продажТаблицаЦена, дата, тип события
Описание объектаТекстМаркетинговый абзац
URL фото (карусель)URL изображений20+ на объявление
Имя, телефон, email агентаТекст / Телефон / EmailТелефон часто скрыт
Рейтинги школ (начальная/средняя/старшая)ЧислоПлюс название округа
Walk / Transit / Bike ScoreЧисло
Оценки климатических рисковЧислоНаводнение, пожар, жара, ветер
Похожие активные / проданные / близкие объектыURLДанные карусели
Парковка, гараж, отопление, охлаждениеТекстГруппы удобств

Поля профиля агента

ПолеТип данныхПримечания
Имя агента, фото, брокерская компания, биоТекст / Изображение
Телефон, форма связиТелефон / ТекстПоказывается по клику
Количество активных объявленийЧисло
Продажи за последние 12 месяцев / общий объёмЧисло
Среднее соотношение цена листинга / цена продажиЧисло
Рейтинг звёздами / количество отзывовЧисло
Опыт работы / номер лицензииТекст / Число

Если использовать функцию Thunderbit AI Suggest Fields на странице Redfin, она автоматически распознаёт большую часть этих колонок и назначает правильные типы данных — без ручной настройки CSS-селекторов. Об этом ещё поговорим ниже.

Как Redfin защищается от ботов: не просто «используйте прокси»

Здесь я хочу сделать важную ремарку: большинство статей просто перескакивают через проблему блокировки и сразу идут к совету «купите прокси у нашего спонсора». Это не помогает. Если не понимать, что именно Redfin делает для выявления парсеров, можно сжечь прокси-лимиты и всё равно получить блок. ScrapeOps оценивает антибот-защиту Redfin на 7,5 из 10, а Scraperly относит её к среднему уровню (3/5) — «менее агрессивно, чем enterprise WAF у Zillow, но с собственным rate limiting и JavaScript-челленджами».

Redfin использует многоуровневую схему: Cloudflare на краю сети (JS challenge, Turnstile, TLS/JA3 fingerprinting) плюс лимитер на уровне приложения, специфичный для Redfin. В их robots.txt нет директивы Crawl-delay, потому что контроль происходит на уровне WAF.

Почему простой requests + BeautifulSoup ломается на Redfin

Если вы отправите обычный requests.get() на страницу объекта Redfin с дефолтными заголовками, обычно происходит одно из трёх:

  • HTTP 403 — JS-челлендж Cloudflare не пройден, и вместо страницы объекта вы получаете страницу проверки.
  • Промежуточная страница проверки — в HTML вместо данных объекта находится виджет Turnstile от Cloudflare.
  • HTTP 200 с частичным HTML — вы получаете оболочку с большим JSON-блоком под root.__reactServerState.InitialContext, но без заранее отрендеренных карточек, истории цен и рейтингов школ.

Redfin использует собственный React SSR framework (не Next.js), а ключ гидратации у него свой — root.__reactServerState.InitialContext, где данные по объекту лежат внутри ReactServerAgent.cache.dataCache. Это не __NEXT_DATA__ и не window.__INITIAL_STATE__.

Самая частая причина «тихих» 403? Отсутствие заголовков Sec-Fetch-*. Redfin/Cloudflare явно проверяет Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest и Sec-Fetch-User. Если их нет, вы сразу попадаете в подозрительную категорию.

План обхода: задержки, заголовки, прокси и сессии

Ниже — полный разбор защит и конкретные способы, как с каждой бороться:

Защита RedfinЧто делаетСигнал обнаруженияСтратегия обхода
JS-челлендж CloudflareПромежуточная страница, выдающая cookie cf_clearance403 + HTML-страница Cloudflarecurl_cffi с impersonate="chrome120"; прогрев сессии через главную страницу; US residential proxy
Cloudflare TurnstileИнтерактивная CAPTCHA для рискованных сессий403 + виджет TurnstileHeadless-браузер со stealth + residential proxy
Cloudflare Error 1020 (бан ASN)Блокирует отмеченные IP/ASN на уровне WAF403 с текстом "Error 1020 Access Denied"Переход на residential/mobile proxy; не используйте datacenter ASN
TLS/JA3 fingerprintingВыявляет TLS-стек, не похожий на браузерТихий 403 даже при идеальных заголовкахИмитация в curl_cffi или настоящий браузер
HTTP/2 fingerprintingПроверяет HTTP/2 SETTINGS и порядок HPACKТихая блокировкаcurl_cffi говорит по HTTP/2 как Chrome
Проверка заголовков (UA, Sec-Fetch-*)Проверяет набор заголовков на соответствие браузеру403 с первого запросаПолный набор заголовков Chrome, включая Sec-Fetch-Site/Mode/Dest/User, реалистичный Referer
Непрерывность cookie/sessionОтслеживает cf_clearance, RF_BROWSER_IDЧелленджи при холодном запросе к deep URLПостоянная сессия; сначала прогрев через главную страницу
Лимит на уровне приложенияОграничение запросов на IP429Задержка 2–5 секунд с jitter; экспоненциальный backoff
Репутация datacenter IPБлокирует известные ASN дата-центровМгновенный 1020/403Только US residential или mobile proxy
Детект параллельностиНесколько одновременных запросов с одного IPРезкая эскалация до TurnstileНе более 2 одновременных запросов на IP

Практические пороги из тестов сообщества:

  • Безопасный темп: 1 запрос каждые 2–3 секунды на IP
  • Стабильно более 20–30 запросов в минуту с одного datacenter IP вызывает челлендж за считанные минуты
  • Мягкие лимиты обычно снимаются через 5–15 минут после остановки трафика
  • Баны datacenter IP (AWS, GCP, Azure, OVH) могут держаться от часов до дней

Обычный Python requests (urllib3 + OpenSSL) даёт JA3 fingerprint, не совпадающий ни с одним браузером — и блокируется тихо, даже если заголовки идеальны. Стандартное решение в индустрии — curl_cffi с impersonate="chrome120", который имитирует TLS и HTTP/2 как у Chrome.

Три способа собрать данные с Redfin на Python и какой выбрать

redfin_methods_dc0828acd4.png

Я не нашёл ни одного нормального обзора, где все три подхода сравниваются бок о бок. Вот таблица выбора:

КритерийРазбор HTML (BS4 + Selenium)Скрытый Stingray APIThunderbit (no-code)
Сложность запускаСредняя (Python + драйвер браузера)Высокая (реверс-инжиниринг эндпоинтов)Низкая (установка расширения Chrome)
Риск блокировкиВысокий (DOM-запросы заметнее всего)Средний (запросы вида API выглядят чище)Самый низкий (использует вашу реальную браузерную сессию)
Качество структуры данныхСреднее (неструктурированный HTML → ручной парсинг)Отличное (уже структурированный JSON)Высокое (AI автоматически определяет поля и типы)
Поддержка и обновленияВысокая нагрузка — любое изменение верстки ломает селекторыСредняя — эндпоинты могут меняться без предупрежденияСамая низкая — AI подстраивается под изменения верстки
МасштабНизкий–средний (сотни запросов с прокси)Средний–высокий (тысячи, более чистые запросы)Средний (50 страниц за раз через cloud scraping)
Лучший вариант дляРазработчики, которым нужен полный контрольРазработчики, которым нужен чистый JSONНердевелоперы, быстрые проекты, постоянные данные без команды разработки

Аспект поддержки особенно важен. Redfin уже выпускал два поколения DOM для карточек — старый (homecardV2Price) и текущий (span.bp-Homecard__Price--value). По истории issue в GitHub видно, что поломка CSS-селекторов происходит примерно каждые 6–12 месяцев. Когда это случается, BeautifulSoup-скрипт ломается за одну ночь. AI-определение полей подстраивается.

Перед началом

  • Сложность: средняя (подходы 1 и 2), начальная (подход 3)
  • Время: около 30 минут для подхода 1 или 2; около 5 минут для подхода 3
  • Что понадобится:
    • Python 3.8+ и pip (подходы 1 и 2)
    • Браузер Chrome (все подходы)
    • Thunderbit Chrome Extension (подход 3)
    • US residential proxies для массового сбора (подходы 1 и 2)

Собирайте данные Redfin с помощью AI Get Started Free

Подход 1: сбор данных Redfin на Python через разбор HTML (BeautifulSoup + Selenium)

Это путь «полного контроля». Вы пишете селекторы, управляете браузером и обрабатываете ошибки.

Это самый обучающий подход. И одновременно самый хрупкий.

Шаг 1: подготовьте окружение Python

Создайте виртуальное окружение и установите нужные библиотеки:

python -m venv redfin-scraper
source redfin-scraper/bin/activate  # В Windows: redfin-scraper\Scripts\activate
pip install requests beautifulsoup4 selenium webdriver-manager pandas curl_cffi

curl_cffi здесь обязателен — именно он позволяет вашим HTTP-запросам имитировать настоящий TLS-fingerprint Chrome, вместо стандартного fingerprint Python requests, который Cloudflare блокирует сразу.

Шаг 2: настройте заголовки браузера и сессию

На этом этапе ошибается большинство новичков. Вам нужен полный набор Chrome-заголовков, включая Sec-Fetch-*, которые Redfin/Cloudflare явно проверяет:

from curl_cffi import requests as curl_requests

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-User": "?1",
}

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# Прогрейте сессию — получите cookies cf_clearance и RF_BROWSER_ID
session.get("https://www.redfin.com/")

Шаг прогрева сессии критичен — если сразу идти на глубокую страницу объекта без cookies и без Referer, Cloudflare понижает доверие к запросу.

Всегда начинайте с главной страницы.

Шаг 3: соберите результаты поиска Redfin

Когда сессия прогрета, можно запрашивать страницу поиска по городу и разбирать карточки объектов. Актуальные селекторы (2024–2026):

import time
import random
from bs4 import BeautifulSoup

base_url = "https://www.redfin.com/city/17151/CA/San-Francisco"
listings = []

for page_num in range(1, 6):  # Страницы 1-5
    url = f"{base_url}/page-{page_num}" if page_num > 1 else base_url
    resp = session.get(url)

    if resp.status_code != 200:
        print(f"Блокировка на странице {page_num}: HTTP {resp.status_code}")
        break

    soup = BeautifulSoup(resp.text, "html.parser")
    cards = soup.select("[data-rf-test-id='property-card'], a.bp-Homecard")

    for card in cards:
        price_el = card.select_one("span.bp-Homecard__Price--value")
        addr_el = card.select_one("a.bp-Homecard__Address")
        stats = card.select("span.bp-Homecard__LockedStat--value")

        listing = {
            "price": price_el.text.strip() if price_el else None,
            "address": addr_el.text.strip() if addr_el else None,
            "beds": stats[0].text.strip() if len(stats) > 0 else None,
            "baths": stats[1].text.strip() if len(stats) > 1 else None,
            "sqft": stats[2].text.strip() if len(stats) > 2 else None,
            "url": "https://www.redfin.com" + addr_el["href"] if addr_el else None,
        }
        listings.append(listing)

    # Случайная задержка 2–5 секунд
    time.sleep(random.uniform(2, 5))

print(f"Собрано {len(listings)} объявлений")

В результате у вас будет растущий список словарей, где для каждого объекта из Сан-Франциско указаны цена, адрес, спальни/ванные/площадь и ссылка на страницу объекта. Если карточек 0, проверьте HTTP-статус — 403 означает, что вас поймал Cloudflare, и, скорее всего, нужны residential proxies.

Шаг 4: соберите данные со страницы конкретного объекта

Страница результатов даёт базу. Страница объекта — это Redfin Estimate, год постройки, HOA, история продаж, данные агента и фото. Эти страницы требуют рендеринга JavaScript, поэтому используем Selenium:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                     "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

for listing in listings[:10]:  # Обогащаем первые 10
    driver.get(listing["url"])
    time.sleep(random.uniform(3, 6))  # Ждём рендеринг JS

    try:
        estimate_el = driver.find_element(By.CSS_SELECTOR, "[data-rf-test-name='avmLdpPrice']")
        listing["redfin_estimate"] = estimate_el.text.strip()
    except:
        listing["redfin_estimate"] = None

    try:
        year_built = driver.find_element(By.XPATH, "//span[contains(text(),'Year Built')]/following-sibling::span")
        listing["year_built"] = year_built.text.strip()
    except:
        listing["year_built"] = None

driver.quit()

После этого первые 10 объявлений будут дополнены значениями Redfin Estimate и годом постройки. XPath-селекторы для таких вложенных полей обычно устойчивее CSS, но всё равно хрупкие — любое изменение DOM может их сломать.

Шаг 5: обработка блокировок и ошибок

Добавьте retry-логику с экспоненциальным backoff:

import time

def fetch_with_retry(session, url, max_retries=3):
    for attempt in range(max_retries):
        resp = session.get(url)
        if resp.status_code == 200:
            return resp
        elif resp.status_code in (403, 429, 503):
            wait = (2 ** attempt) + random.uniform(1, 3)
            print(f"Блокировка ({resp.status_code}). Повтор через {wait:.1f}с...")
            time.sleep(wait)
        else:
            print(f"Неожиданный статус: {resp.status_code}")
            break
    return None

Признаки блокировки: HTTP 403 с HTML Cloudflare в теле ответа, HTTP 429 (явный rate limit), пустое тело ответа или текст "Error 1020 Access Denied" в содержимом страницы. Если это происходит постоянно, пора подключать residential proxies или переходить к API-подходу.

Подход 2: сбор данных Redfin на Python через скрытый Stingray API

Это мой любимый способ. Фронтенд Redfin обращается к внутреннему JSON API на /stingray/api/home/details/*, а ответы приходят в виде чистого типизированного JSON — без разбора HTML.

Как найти скрытые эндпоинты Redfin

Откройте Chrome DevTools → вкладка Network → фильтр Fetch/XHR → перейдите на любую страницу объекта Redfin. Вы увидите запросы к таким эндпоинтам:

  • api/home/details/initialInfo — сопоставляет URL → propertyId, listingId
  • api/home/details/aboveTheFold — цена, спальни, ванные, площадь, фото, статус, агент, MLS#
  • api/home/details/belowTheFold — удобства, HOA, налоги, парковка, год постройки, участок, история
  • api/home/details/avm — Redfin Estimate для объекта в продаже
  • api/home/details/owner-estimate — Redfin Estimate для объекта вне рынка
  • api/home/details/descriptiveParagraph — маркетинговое описание

Для страниц аренды rentalId (UUID из 36 символов) извлекается из URL тега <meta property="og:image">.

Сбор данных об объекте через Stingray API

Есть важная особенность: ответы Stingray JSON начинаются с буквального префикса {}&& как анти-CSRF-мера. Перед парсингом его нужно удалить:

import json
from curl_cffi import requests as curl_requests

session = curl_requests.Session(impersonate="chrome120")
session.headers.update(HEADERS)

# Прогрев сессии
session.get("https://www.redfin.com/")

# Сначала открываем страницу объекта, чтобы получить cookies и property ID
property_url = "https://www.redfin.com/CA/San-Francisco/123-Main-St-94102/home/12345678"
page_resp = session.get(property_url)

# Теперь обращаемся к Stingray API
api_url = "https://www.redfin.com/stingray/api/home/details/aboveTheFold?propertyId=12345678"
api_resp = session.get(api_url, headers={"Referer": property_url})

# Убираем анти-CSRF-префикс
payload = json.loads(api_resp.text.replace("{}&&", "", 1))

# Извлекаем структурированные данные
listing_data = payload.get("payload", {})
print(json.dumps(listing_data, indent=2))

Ответ содержит типизированные поля: цена как целое число, спальни/ванные как числа, URL фото как массив, данные агента как вложенные объекты. Никакого BeautifulSoup, CSS-селекторов и угадывания.

Плюсы и ограничения скрытого API-подхода

Плюсы:

  • Уже структурированный JSON — гораздо чище, чем HTML-парсинг
  • Быстрее на запрос — меньше размер ответа, нет затрат на рендеринг
  • Ниже риск блокировки — запросы в стиле API с правильными заголовками выглядят естественнее

Ограничения:

  • Эндпоинты могут меняться без предупреждения — официальной документации нет
  • В robots.txt явно запрещён путь /stingray/ для wildcard user-agent
  • Для поиска новых эндпоинтов нужен реверс-инжиниринг
  • Всё равно нужны прогрев сессии и корректные заголовки, чтобы избежать Cloudflare

No-code альтернатива: собирайте данные Redfin с Thunderbit

Если вам нужны данные Redfin, но вы не хотите поддерживать Python-скрипты — или просто хотите получить результат за пять минут — начните отсюда. Мы создали Thunderbit именно для этого: извлечение структурированных данных с любого сайта без кода.

Шаг 1: установите Thunderbit и откройте Redfin

Установите Thunderbit Chrome Extension из Chrome Web Store. Откройте Redfin и перейдите на страницу результатов поиска — например, объекты на продажу в Сан-Франциско.

Шаг 2: нажмите «AI Suggest Fields»

Нажмите иконку Thunderbit на панели браузера, затем выберите "AI Suggest Fields". ИИ читает страницу Redfin и автоматически предлагает колонки вроде «Address», «Price», «Beds», «Baths», «SqFt», «Property Type» и «Listing Photo» — с корректно назначенными типами данных.

Вы можете удалить ненужные колонки или добавить свои, нажав "+ Add Column" и описав нужное обычным английским языком, например «listing agent name» или «days on market».

После этого вы увидите предварительный просмотр таблицы с настроенными колонками, готовыми к заполнению.

Шаг 3: нажмите «Scrape» и наблюдайте, как данные заполняются

Нажмите кнопку "Scrape". Thunderbit обработает видимые объявления и заполнит таблицу. Для страниц с пагинацией он автоматически переходит между страницами — никаких циклов писать не нужно.

По моим тестам, таблица на 50 строк заполняется примерно за 45 секунд. Структурированные данные, готовые к экспорту.

Как Thunderbit обходит антибот-защиту Redfin

Поскольку Thunderbit работает внутри вашего собственного браузера, он использует ваши существующие cookies Redfin, сессию и браузерный fingerprint. Для Cloudflare это выглядит как обычный пользователь, который просто зашёл на Redfin — потому что технически так и есть. Здесь нет headless-браузера, нет datacenter IP и нет несоответствия TLS fingerprint. Для общедоступных страниц cloud scraping в Thunderbit может обрабатывать до 50 страниц за раз.

Это принципиально другая модель, чем отправка requests из Python-скрипта на сервере.

Ваша браузерная сессия уже считается доверенной.

Сбор подстраниц Redfin в Thunderbit

После сбора результатов поиска нажмите "Scrape Subpages", и ИИ посетит каждую страницу объекта, чтобы обогатить таблицу дополнительными полями — Redfin Estimate, год постройки, HOA dues, данные агента, фото объекта и история продаж.

Это аналог того самого 40-строчного цикла Selenium из первого подхода — только в один клик и без поддержки кода.

Когда Redfin меняет DOM с homecardV2Price на span.bp-Homecard__Price--value, ИИ подстраивается. Ваши Python-селекторы — нет.

Собирайте подстраницы Redfin с помощью AI Get Started Free

Не только CSV: экспорт данных Redfin в Google Sheets, Airtable и Notion

Большинство туториалов заканчиваются на df.to_csv(). Для разового анализа этого достаточно. Но если вы работаете в команде по недвижимости, вам нужны живые совместные данные, а не статические файлы, которые пылятся на чьём-то рабочем столе.

Экспорт через Python (gspread + Airtable API)

Google Sheets через gspread:

import gspread
import pandas as pd
from gspread_dataframe import set_with_dataframe

df = pd.DataFrame(listings)
gc = gspread.service_account(filename="service_account.json")
sh = gc.open("Redfin Listings")
ws = sh.worksheet("Sheet1")
ws.clear()
set_with_dataframe(ws, df, include_index=False, resize=True)

# Отображение фото в ячейках через формулу IMAGE()
image_col = df.columns.get_loc("image_url") + 1
for row_idx, url in enumerate(df["image_url"], start=2):
    ws.update_cell(row_idx, image_col, f'=IMAGE("{url}")')

Учтите: у Google Sheets жёсткий лимит в 10 миллионов ячеек на таблицу, а API допускает 300 read + 300 write запросов в минуту на проект. Для всего, что больше нескольких десятков строк, используйте ws.batch_update() вместо поячеечных циклов.

Airtable через pyairtable:

Критическое изменение 2024 года: Airtable отказался от legacy API keys 1 февраля 2024 года. Теперь нужно использовать Personal Access Tokens (PATs) — любой туториал, где всё ещё указан api_key=..., уже нерабочий.

from pyairtable import Api

api = Api("patXXXXXXXXXXXXXX.yyyyyyyyyyyyyyyyyyyy")
table = api.table("appBaseId123", "Redfin Listings")

records = [
    {
        "Address": row["address"],
        "Price": row["price"],
        "Beds": row["beds"],
        "Photo": [{"url": row["image_url"]}],  # Airtable забирает файл и размещает у себя
    }
    for row in listings
]
created = table.batch_create(records, typecast=True)

У Airtable лимит 5 запросов в секунду на базу, а при нарушении — блокировка на 30 секунд. Поле вложений принимает payload вида [{"url": ...}] — серверы Airtable сами забирают файл, размещают его на своём CDN и автоматически создают миниатюры.

Экспорт через Thunderbit: 1 клик в Sheets, Airtable и Notion

У Thunderbit есть встроенный экспорт в Google Sheets, Airtable и Notion в один клик — и вот чем я особенно горжусь: фотографии объектов загружаются и отображаются как встроенные изображения в Notion и Airtable. Никаких костылей с =IMAGE() и никаких битых CDN-ссылок. Вы нажимаете «Export to Airtable», и команда получает визуальную базу объектов с миниатюрами, которую удобно просматривать даже с телефона.

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

Законно ли собирать данные Redfin? Что говорят ToS, robots.txt и судебная практика

Я не юрист, и это не юридическая консультация. Но после многих лет работы с извлечением данных могу сказать: вопрос «законно ли это?» задают все, а большинство туториалов его обходят.

robots.txt у Redfin

robots.txt у Redfin довольно подробный. Главное:

  • Полностью заблокированные боты: peer39_crawler/1.0, AmazonAdBot, FireCrawlAgent — Redfin прямо называет популярный сервис для парсинга из эпохи LLM
  • Запреты для wildcard User-agent: *: /stingray/ (вся внутренняя API-зона), /myredfin/, /api/v1/rentals/, /api/v1/properties/, /owner-estimate/
  • Нет директивы Crawl-delay: ни для одного user-agent
  • Указано более 50 sitemap — sitemap остаются самым чистым и наименее конфликтным способом перечисления URL

Условия использования Redfin

Раздел 2.3.5 гласит: "You may not automatedly crawl or query the Services for any purpose or by any means... unless you have received prior express written permission."

Это browsewrap-соглашение — принятие условий происходит за счёт продолжения использования, а не через явное clickwrap-согласие. Американские суды исторически относились к enforceability browsewrap скептически, если у пользователя не было реального уведомления (см. Nguyen v. Barnes & Noble, 9th Cir. 2014).

Релевантная судебная практика (кратко)

  • Van Buren v. United States (Верховный суд, 2021): формулировка CFAA «exceeds authorized access» трактуется по тесту «шлагбаум вверх или вниз». Использование открытой двери не по назначению — это не федеральный хакерский доступ.
  • hiQ Labs v. LinkedIn (9th Cir., 2022): сбор публично доступных данных не нарушает CFAA. Но hiQ в итоге заплатила $500,000 по мировому соглашению по договорным основаниям — потому что у них были зарегистрированы аккаунты LinkedIn и нажато «I agree».
  • Meta Platforms v. Bright Data (N.D. Cal., янв. 2024): суд вынес summary judgment в пользу Bright Data — сбор публичных данных в состоянии logout не делал Bright Data «пользователем», связанным ToS Meta.
  • X Corp. v. Bright Data (N.D. Cal., май 2024): судья Alsup отклонил требования X, указав, что претензии по закону штата, направленные на контроль копирования публичного контента, вытесняются Copyright Act.

Практические рекомендации

  • Собирайте только общедоступные данные — никогда не регистрируйте аккаунт с последующим парсингом (это создаёт риск по clickwrap-контракту)
  • Соблюдайте лимиты скорости — агрессивные объёмы могут поддержать претензии по trespass to chattels
  • Не публикуйте массово исходные данные или фото — иск CoStar v. Zillow (подан в июле 2025 года, потенциальный ущерб более $1 млрд) напоминает, что авторские права на фото — серьёзная тема
  • Подход Thunderbit на базе браузера — работа в вашей собственной авторизованной сессии — ближе к «ручному просмотру на машинной скорости», чем к headless-боту в дата-центре, а значит, это наиболее защищаемая позиция, если только у вас нет лицензированного API

Советы и типичные ошибки

Несколько уроков, добытых в бою при создании инструментов извлечения и наблюдении за тем, как тысячи пользователей собирают данные с сайтов недвижимости:

  • Всегда прогревайте сессию. Сначала откройте redfin.com/, а уже потом идите на глубокий URL. Холодный заход на deep URL — это №1 триггер для Cloudflare-челленджа.
  • Реалистично ротируйте User-Agent. Не используйте один и тот же — лучше иметь 5–10 актуальных UA для Chrome/Firefox. Но не ротируйте их слишком агрессивно: разные UA на каждом запросе выглядят подозрительно.
  • Дедуплицируйте по ID объекта. Пагинация Redfin иногда пересекается. Парсите /home/{id} из каждого URL объявления и убирайте дубликаты до этапа обогащения.
  • Если можете, не собирайте данные в часы пик. По моему опыту, поздняя ночь и раннее утро по времени США вызывают меньше внимания со стороны WAF.
  • При 429 используйте экспоненциальный backoff. Не пробуйте сразу ещё раз — так вы рискуете перейти от мягкого лимита к жёсткому бану IP.
  • Для крупных проектов (1000+ страниц) закладывайте бюджет на residential proxies. Datacenter IP (AWS, GCP, Azure, OVH) уже занесены в чёрные списки системой репутации ASN Cloudflare. Ошибка 1020 появится почти сразу.

Как выбрать правильный способ сбора данных Redfin

Итак, какой подход выбрать? Всё зависит от того, кто вы и что вам нужно.

Разбор HTML (BeautifulSoup + Selenium): лучший вариант для разработчиков, которым нужен полный контроль, которые готовы поддерживать CSS-селекторы и не боятся переписывать код при изменении DOM у Redfin. Закладывайте пересмотр кода каждые 6–12 месяцев.

Скрытый Stingray API: подходит разработчикам, которым нужен чистый структурированный JSON и которые готовы заниматься реверс-инжинирингом недокументированных эндпоинтов. Поддерживать его проще, чем HTML-парсинг, но эндпоинты могут меняться без предупреждения. И помните: /stingray/ прямо запрещён в robots.txt.

Thunderbit (no-code): лучший выбор для тех, кто не пишет код, для быстрых проектов и команд, которым нужны регулярные данные Redfin без участия разработчиков. AI адаптируется к изменениям верстки, сбор подстраниц обогащает данные в один клик, а экспорт в Google Sheets, Airtable или Notion уже встроен. Если вам нужна живая база объектов, а не разовый CSV-дамп, это путь с наименьшим сопротивлением.

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

Готовы попробовать no-code вариант? Бесплатный тариф Thunderbit позволит поэкспериментировать со сбором данных Redfin и увидеть результат за считанные минуты. Для Python-подходов приведённые выше фрагменты кода — рабочая стартовая точка, просто добавьте прокси и немного терпения.

Попробовать Thunderbit для постоянного сбора данных Redfin

FAQ

Есть ли у Redfin публичный API?

Нет. У Redfin нет официального публичного API. Скрытый Stingray API (/stingray/api/home/details/*) возвращает структурированный JSON и используется фронтендом Redfin, но он неофициальный, не задокументирован, может измениться без предупреждения и прямо запрещён в robots.txt Redfin. Open-source-обёртки вроде reteps/redfin на PyPI дают доступ из Python, но использовать их нужно с пониманием рисков.

Можно ли собирать данные Redfin без Python?

Да. Thunderbit — это AI-расширение для Chrome, которое использует вашу браузерную сессию для устойчивости к антибот-защите: установите его, откройте Redfin, нажмите "AI Suggest Fields" и экспортируйте данные в Excel, Google Sheets, Airtable или Notion. На рынке также есть другие no-code инструменты и готовые поставщики датасетов, если хочешь рассмотреть альтернативы.

Как часто Redfin меняет интерфейс сайта?

По истории issue в GitHub видно, что CSS-селекторы ломаются примерно каждые 6–12 месяцев. Redfin выпускал два поколения DOM для карточек — старые (homecardV2Price, homeAddressV2) и текущие (bp-Homecard__Price--value, bp-Homecard__Address). Зрелые парсеры обычно пробуют оба варианта по очереди.

AI-инструменты вроде Thunderbit адаптируются автоматически, потому что определяют поля по содержимому, а не по CSS-селекторам.

Какой тип прокси лучше всего подходит для Redfin?

Для массового сбора — US residential proxies: по бенчмаркам сообщества их успешность около 80%. Datacenter proxies почти сразу получают Cloudflare Error 1020; диапазоны AWS, GCP, Azure и OVH уже в чёрных списках. Mobile proxies дают самый высокий процент успеха, но стоят в 5–10 раз дороже.

Для небольшого личного сбора (<100 страниц) иногда достаточно правильных заголовков + curl_cffi impersonation + задержек 2–5 секунд — без прокси вообще.

Можно ли собирать данные о проданных или off-market объектах из Redfin?

Да. Данные о проданных объектах и off-market Redfin Estimate (медианная ошибка 7,52%) доступны на страницах объектов и собираются теми же подходами. Поля отличаются от активных объявлений: на off-market страницах доступны цена продажи, дата продажи, история объекта и endpoint owner-estimate, но нет текущей цены листинга, дней на рынке и информации об open house. Эндпоинт Stingray API для off-market-оценки — api/home/details/owner-estimate, а не api/home/details/avm.

Попробуйте Thunderbit для сбора данных с Redfin Get Started Free

Подробнее

Shuai Guan
Shuai Guan
Генеральный директор Thunderbit | Эксперт по автоматизации данных с помощью ИИ Shuai Guan — генеральный директор Thunderbit и выпускник инженерного факультета Мичиганского университета. Опираясь почти на десятилетний опыт в сфере технологий и SaaS-архитектуры, он специализируется на том, чтобы превращать сложные модели ИИ в практичные no-code инструменты для извлечения данных. В этом блоге он делится честными, проверенными в деле инсайтами о веб-скрейпинге и стратегиях автоматизации, чтобы помочь вам выстраивать более умные, data-driven рабочие процессы. Когда он не занимается оптимизацией потоков данных, тот же внимательный подход к деталям он переносит в своё увлечение фотографией.
Содержание

Собирай страницу, просто задав вопрос

Скажи, что тебе нужно, простыми словами. А ещё лучше — ничего не говори.

Попробовать Thunderbit бесплатно
Извлекай данные с помощью ИИ
Легко передавай данные в Google Sheets, Airtable или Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week