Scrape Bất Động Sản Với Python: Thu Thập Dữ Liệu Nhà Đất
Bất động sản là ngành có nhiều data cần scrape. Bài viết hướng dẫn scrape listings nhà đất từ các trang phổ biến.
Use Cases
- Price analysis: Giá theo khu vực
- Investment research: Tìm deals tốt
- Market trends: Xu hướng giá
- Agent tools: Database listings
Các Trang BĐS Việt Nam
- batdongsan.com.vn
- nha.chotot.com
- homedy.com
- muaban.net
Data Points Cần Thu Thập
- Tiêu đề, mô tả
- Giá (tổng, /m²)
- Diện tích
- Địa chỉ, quận/huyện
- Số phòng ngủ/WC
- Hướng nhà
- Ngày đăng
- Thông tin liên hệ
Scraper Code
import requests
from bs4 import BeautifulSoup
import re
import json
def scrape_listing(url):
response = requests.get(url, headers={
'User-Agent': 'Mozilla/5.0...'
})
soup = BeautifulSoup(response.text, 'lxml')
# Extract data
title = soup.select_one('h1.title').text.strip()
# Price - handle various formats
price_text = soup.select_one('.price').text
price = parse_price(price_text)
# Area
area_text = soup.select_one('.area').text
area = float(re.search(r'[\d.]+', area_text).group())
# Location
address = soup.select_one('.address').text.strip()
district = extract_district(address)
# Details
details = {}
for row in soup.select('.detail-row'):
label = row.select_one('.label').text.strip()
value = row.select_one('.value').text.strip()
details[label] = value
return {
'title': title,
'price': price,
'price_per_m2': price / area if area else None,
'area': area,
'address': address,
'district': district,
'bedrooms': details.get('Phòng ngủ'),
'bathrooms': details.get('Phòng tắm'),
'url': url
}
def parse_price(text):
# "3.5 tỷ" -> 3500000000
# "500 triệu" -> 500000000
text = text.lower()
number = float(re.search(r'[\d.]+', text).group())
if 'tỷ' in text:
return number * 1_000_000_000
elif 'triệu' in text:
return number * 1_000_000
return number
Scrape Listings Page
def scrape_listings_page(url):
response = requests.get(url, headers={'User-Agent': '...'})
soup = BeautifulSoup(response.text, 'lxml')
listings = []
for item in soup.select('.listing-item'):
listing_url = item.select_one('a')['href']
listings.append(listing_url)
return listings
# Scrape multiple pages
all_listings = []
for page in range(1, 11):
url = f'https://batdongsan.com.vn/ban-nha?page={page}'
listing_urls = scrape_listings_page(url)
for listing_url in listing_urls:
data = scrape_listing(listing_url)
all_listings.append(data)
time.sleep(2) # Delay
print(f"Page {page}: {len(listing_urls)} listings")
Analysis
import pandas as pd
df = pd.DataFrame(all_listings)
# Giá trung bình theo quận
avg_by_district = df.groupby('district')['price_per_m2'].mean()
print(avg_by_district.sort_values(ascending=False))
VinaProxy + Real Estate Scraping
- IP Việt Nam cho local sites
- Bypass anti-scraping
- Giá chỉ $0.5/GB
