Як зібрати дані про нерухомість: повний гайд
Вебскрапінг даних про нерухомість із вебсайтів створює унікальні виклики. Сайти з оголошеннями про нерухомість використовують рендеринг JavaScript, динамічне підвантаження контенту та антибот-захист, який блокує традиційні вебскрапери. Цей посібник описує практичні рішення із застосуванням Python and Інструменти Bright Data.
'axios' Я не пов’язаний із Bright Data. Це платформа, з якою я найкраще знайомий, тому обрав її для цього прикладу.
Чому вебскрапінг даних про нерухомість є складним
Сайти нерухомості створюють три основні перешкоди:
1. Сторінки-списки vs. детальні сторінки
Результати пошуку показують лише обмежений набір даних (ціна, адреса, мініатюра). Повні відомості про об’єкт — квадратура, історія об’єкта, дані про агента — потребують переходу на окремі сторінки оголошень, що кратно збільшує кількість необхідних запитів.
2. JavaScript Rendering
Більшість сайтів нерухомості рендерять контент на боці клієнта. Простий HTTP-запит повертає неповний HTML, бо дані завантажуються через JavaScript після первинного завантаження сторінки.
3. Anti-Bot Protection
Сайти впроваджують IP-фільтрацію, CAPTCHA, обмеження частоти запитів і виявлення за браузерним відбитком, щоб виявляти та блокувати вебскраперів.
Базовий вебскрапер на Requests і BeautifulSoup
Цей підхід працює для простих сайтів без складних антибот-механізмів.
Аналіз цільової сторінки
Перед написанням коду вивчіть структуру сторінки:
- Відкрийте результати пошуку у браузері
- Клацніть правою кнопкою миші на оголошенні про нерухомість і виберіть «Перевірити»
- Визначте HTML-елементи, що містять потрібні вам дані (ціна, адреса, посилання)
Installation
pip install requests beautifulsoup4
Basic Scraper Code
import requests
from bs4 import BeautifulSoup
import csv
url = "https://www.example.com/homes/for_sale/San-Francisco/"
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"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
results = []
property_items = soup.find_all("li", {"data-testid": "property-card"})
for item in property_items:
try:
address = item.find("address").get_text(strip=True)
price = item.find("span", {"data-test": "property-card-price"}).get_text(strip=True)
url_link = item.find("a").get("href")
full_url = f"https://www.example.com{url_link}" if url_link and not url_link.startswith("http") else url_link
if address or price:
results.append({
"address": адреса,
"price": price,
"link": full_url
})
except Exception as e:
print(f"Error parsing card: {e}")
if results:
with open("real_estate_data.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["address", "price", "link"])
writer.writeheader()
writer.writerows(results)
print(f"Scraped {len(results)} listings")
else:
print(f"Failed to fetch page. Status code: {response.status_code}")
Limitation: Цей підхід не працює на сайтах із рендерингом JavaScript або антибот-захистом.
Робота з антибот-захистом за допомогою Bright Data
Коли базовий вебскрапінг не дає результатів, Bright Data пропонує кілька рішень залежно від ваших потреб.
Варіант 1: Unlocker APIs (рекомендовано для статичних сторінок)
Unlocker API обробляють ротація проксі, Розв’язання CAPTCHA, and anti-bot bypassing automatically. You send one request; it returns clean HTML or JSON.
Найкраще для:
- Сторінки, які не потребують взаємодії з браузером
- Масовий вебскрапінг із передбачуваними витратами
- Команди без проксі-інфраструктури
Прямий доступ до API (рекомендований метод)
import requests
API_KEY = "YOUR_API_KEY"
ZONE_NAME = "YOUR_ZONE_NAME"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"zone": ZONE_NAME,
"url": "https://www.example.com/homes/for_sale/San-Francisco/",
"format": "raw"
}
response = requests.post(
"https://api.brightdata.com/request",
headers=headers,
json=payload
)
if response.status_code == 200:
html_content = response.text
# Parse with BeautifulSoup
soup = BeautifulSoup(html_content, 'html.parser')
# Extract data as shown above
Native Proxy-Based Access
Для робочих процесів, які вже використовують маршрутизацію через проксі:
import requests
host = 'brd.superproxy.io'
port = 33335
username = 'brd-customer--zone-'
password = ''
proxy_url = f'http://{username}:{password}@{host}:{port}'
proxies = {
'http': proxy_url,
'https': proxy_url
}
url = "https://www.example.com/homes/for_sale/San-Francisco/"
response = requests.get(url, proxies=proxies)
'axios' Для нативного доступу через проксі встановіть SSL-сертифікат Bright Data, щоб уникнути SSL-помилок, або задайте
verify=Falseу ваших запитах (не рекомендовано для продакшну).
Handling JavaScript-Rendered Content
Якщо сторінки повертають неповні дані, використовуйте x-unblock-expect заголовок для очікування конкретних елементів:
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"zone": ZONE_NAME,
"url": "https://www.example.com/property/12345",
"format": "raw",
"headers": {
"x-unblock-expect": '{"element": ".property-details"}'
}
}
Option 2: Browser API (For Interactive Pages)
When you need full browser interaction — clicking buttons, scrolling, handling login flows — use the Browser API. For other tools, read my article about the best scraping browsers.
Найкраще для:
- JavaScript-heavy sites requiring interaction
- Multi-step navigation flows
- Sites with complex anti-bot detection
Puppeteer Example
const puppeteer = require('puppeteer-core');
const AUTH = 'YOUR_USERNAME:YOUR_PASSWORD';
const TARGET_URL = 'https://www.example.com/homes/for_sale/San-Francisco/';
async function scrapeRealEstate() {
const browserWSEndpoint = `wss://${@brd.superproxy.io">AUTH}@brd.superproxy.io:9222`;
const browser = await puppeteer.connect({ browserWSEndpoint });
try {
const page = await browser.newPage();
await page.goto(TARGET_URL, { timeout: 120000 });
// Wait for listings to load
await page.waitForSelector('[data-testid="property-card"]');
// Extract data
const listings = await page.evaluate(() => {
const cards = document.querySelectorAll('[data-testid="property-card"]');
return Array.from(cards).map(card => ({
address: card.querySelector('address')?.textContent?.trim(),
price: card.querySelector('[data-test="property-card-price"]')?.textContent?.trim(),
link: card.querySelector('a')?.href
}));
});
console.log(listings);
} finally {
await browser.close();
}
}
scrapeRealEstate();
Playwright Example
from playwright.sync_api import sync_playwright
AUTH = 'YOUR_USERNAME:YOUR_PASSWORD'
def scrape_real_estate():
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(f'wss://{@brd.superproxy.io">AUTH}@brd.superproxy.io:9222')
page = browser.new_page()
page.goto('https://www.example.com/homes/for_sale/San-Francisco/', timeout=120000)
page.wait_for_selector('[data-testid="property-card"]')
listings = page.evaluate('''() => {
const cards = document.querySelectorAll('[data-testid="property-card"]');
return Array.from(cards).map(card => ({
address: card.querySelector('address')?.textContent?.trim(),
price: card.querySelector('[data-test="property-card-price"]')?.textContent?.trim(),
link: card.querySelector('a')?.href
}));
}''')
browser.close()
return listings
Варіант 3: Web Scraper API (Готові вебскрапери)
Для популярних сайтів нерухомості, як-от Zillow, Realtor.com, або Redfin, Bright Data та інші провайдери пропонують готові вебскрапери, які одразу повертають структуровані дані.
import requests
API_KEY = "YOUR_API_KEY"
DATASET_ID = "gd_xxxxx" # Real estate scraper ID
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Synchronous scraping (up to 20 URLs)
response = requests.post(
f"https://api.brightdata.com/datasets/v3/scrape?dataset_id={DATASET_ID}&format=json",
headers=headers,
json=[{"url": "https://www.zillow.com/homedetails/123-main-st/12345_zpid/"}]
)
data = response.json()
Пагінація та кілька сторінок
Списки нерухомості охоплюють кілька сторінок. Обробляйте пагінацію, ітеруючись за номерами сторінок:
import requests
from bs4 import BeautifulSoup
import time
API_KEY = "YOUR_API_KEY"
ZONE_NAME = "YOUR_ZONE_NAME"
BASE_URL = "https://www.example.com/homes/for_sale/San-Francisco/"
all_results = []
for page_num in range(1, 6):
url = f"{BASE_URL}?page={page_num}"
payload = {
"zone": ZONE_NAME,
"url": url,
"format": "raw"
}
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json=payload
)
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
# Parse and append results
# ...
time.sleep(1) # Basic rate limiting
Витягнення повних даних про об’єкт нерухомості
Сторінки зі списком оголошень містять обмежений обсяг даних. Для повної інформації виконуйте вебскрапінг окремих сторінок об'єктів:
def scrape_property_details(property_url, api_key, zone_name):
payload = {
"zone": zone_name,
"url": property_url,
"format": "raw"
}
response = requests.post(
"https://api.brightdata.com/request",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json=payload
)
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
return {
"description": soup.find("div", {"data-testid": "description"})?.get_text(strip=True),
"bedrooms": soup.find("span", {"data-testid": "beds"})?.get_text(strip=True),
"bathrooms": soup.find("span", {"data-testid": "baths"})?.get_text(strip=True),
"sqft": soup.find("span", {"data-testid": "sqft"})?.get_text(strip=True),
}
return None
# Enrich listing data
for listing in results:
details = scrape_property_details(listing["link"], API_KEY, ZONE_NAME)
if details:
listing.update(details)
Вибір відповідного продукту

Summary
- Почніть із простого за допомогою requests і BeautifulSoup для простих сайтів
- Use Unlocker API коли ви стикаєтеся з антибот-захистом на статичних сторінках
- Перейдіть на Browser API коли сторінки потребують взаємодії за допомогою JavaScript
- Розгляньте Web Scraper API для популярних сайтів із готовими вебскраперами
- Обробка пагінації щоб збирати дані з кількох сторінок
- Вебскрапінг сторінок із детальною інформацією для повної інформації про об’єкт нерухомості

