1. 项目背景与核心价值
在当前的房地产市场中,租房数据分析系统正成为房产中介、个人房东和租房者的重要决策工具。这个基于Python+Django的毕业设计项目,通过爬虫技术获取真实房源数据,运用K-means聚类和线性回归算法进行深度分析,最终以可视化形式呈现市场趋势和房源特征。
这个系统的独特之处在于:
- 实现了从数据采集到分析展示的完整闭环
- 结合了机器学习算法与业务场景的实际应用
- 提供了多维度的可视化交互界面
- 采用Django框架构建完整的Web应用系统
对于计算机专业毕业生而言,这个项目能充分展示以下核心能力:
- 全栈开发能力(前端+后端+数据库)
- 数据爬取与清洗技术
- 机器学习算法应用
- 数据可视化实现
- 系统架构设计思维
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型分析
本系统采用分层架构设计,各层技术选型如下:
| 层级 | 技术组件 | 选型理由 |
|---|---|---|
| 数据采集层 | Scrapy + Playwright | Scrapy提供成熟的爬虫框架,Playwright解决动态页面渲染问题 |
| 数据处理层 | Pandas + NumPy | 提供高效的数据结构和计算能力 |
| 算法层 | Scikit-learn | 包含K-means和线性回归等成熟算法实现 |
| 存储层 | MySQL + Redis | MySQL存储结构化数据,Redis用于缓存和会话管理 |
| 应用层 | Django + Django REST Framework | 快速构建Web应用和API接口 |
| 可视化层 | ECharts + Highcharts | 丰富的图表类型和交互功能 |
2.2 系统模块划分
系统主要分为以下功能模块:
- 爬虫模块:负责从各大租房平台抓取房源数据
- 数据清洗模块:处理缺失值、异常值和数据标准化
- 分析模块:执行聚类和回归算法
- 可视化模块:生成交互式图表
- 用户模块:处理用户注册、登录和权限管理
- API模块:提供数据接口服务
提示:在实际开发中,建议采用Django的app机制来组织这些模块,每个功能模块作为一个独立的Django app,便于维护和扩展。
3. 核心功能实现细节
3.1 Scrapy爬虫实现
房源数据采集是整个系统的基础,我们采用Scrapy框架结合Playwright来处理动态加载内容。以下是核心爬虫类的实现示例:
python复制import scrapy
from scrapy_playwright.page import PageMethod
class RentalSpider(scrapy.Spider):
name = 'lianjia'
def start_requests(self):
url = "https://sh.lianjia.com/zufang/"
yield scrapy.Request(
url,
meta={
"playwright": True,
"playwright_page_methods": [
PageMethod("wait_for_selector", ".content__list--item"),
],
},
callback=self.parse
)
async def parse(self, response):
items = response.css(".content__list--item")
for item in items:
yield {
"title": item.css(".content__list--item-title a::text").get(),
"price": item.css(".content__list--item-price em::text").get(),
"area": item.css(".content__list--item-desktop::text").re_first(r"(\d+)㎡"),
"location": "".join(item.css(".content__list--item--des a::text").getall()),
"tags": item.css(".content__list--item--bottom on::text").getall()
}
关键点说明:
- 使用Playwright处理页面动态渲染,通过wait_for_selector确保目标元素加载完成
- CSS选择器提取房源关键信息
- 正则表达式处理面积等特定格式数据
- 使用异步解析提高爬取效率
3.2 数据清洗与预处理
原始爬取数据通常包含大量噪声,需要进行以下处理步骤:
- 缺失值处理:
python复制df['price'].fillna(df['price'].median(), inplace=True)
df['area'].interpolate(method='linear', inplace=True)
- 异常值过滤:
python复制Q1 = df['price'].quantile(0.25)
Q3 = df['price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['price'] < (Q1 - 1.5 * IQR)) | (df['price'] > (Q3 + 1.5 * IQR)))]
- 特征工程:
python复制# 创建价格区间标签
df['price_level'] = pd.cut(df['price'],
bins=[0, 3000, 5000, 8000, float('inf')],
labels=['低', '中低', '中高', '高'])
# 提取行政区信息
df['district'] = df['location'].str.extract(r'(.+?区)')
3.3 K-means聚类实现
对房源进行聚类分析可以帮助发现市场中的房源群体特征:
python复制from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# 选择特征列
features = df[['price', 'area', 'room_count']]
# 数据标准化
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)
# 使用肘部法则确定最佳K值
inertias = []
for k in range(1, 11):
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(scaled_features)
inertias.append(kmeans.inertia_)
# 可视化肘部曲线确定K=3
kmeans = KMeans(n_clusters=3, random_state=42)
df['cluster'] = kmeans.fit_predict(scaled_features)
聚类结果分析技巧:
- 结合业务解释每个簇的特征
- 计算每个簇的中心点坐标
- 分析各簇在原始特征空间的分布
- 可视化展示聚类结果
3.4 线性回归分析
预测租金价格是租房者的核心需求,我们构建以下回归模型:
python复制from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 准备特征和目标变量
X = df[['area', 'room_count', 'floor', 'district_encoded']]
y = df['price']
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
model = LinearRegression()
model.fit(X_train, y_train)
# 评估模型
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"模型R²分数: {r2:.2f}")
print(f"特征重要性: {dict(zip(X.columns, model.coef_))}")
模型优化方向:
- 尝试多项式特征扩展
- 加入交互特征
- 使用正则化方法防止过拟合
- 考虑其他回归算法如随机森林
4. Django系统实现
4.1 项目结构设计
标准的Django项目结构如下:
code复制rental_analysis/
├── manage.py
├── rental_analysis/
│ ├── settings.py
│ ├── urls.py
│ └── ...
├── crawler/ # 爬虫应用
├── analysis/ # 数据分析应用
├── visualization/ # 可视化应用
└── frontend/ # 前端模板
4.2 核心Model设计
房源数据模型示例:
python复制from django.db import models
class RentalHouse(models.Model):
title = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10, decimal_places=2)
area = models.FloatField()
room_count = models.IntegerField()
floor = models.CharField(max_length=20)
district = models.CharField(max_length=50)
cluster = models.IntegerField(null=True, blank=True)
predicted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
indexes = [
models.Index(fields=['district']),
models.Index(fields=['price']),
]
def __str__(self):
return f"{self.title} - {self.price}元"
4.3 视图与路由配置
数据API视图示例:
python复制from rest_framework.views import APIView
from rest_framework.response import Response
from .models import RentalHouse
from .serializers import RentalHouseSerializer
class RentalListAPI(APIView):
def get(self, request):
queryset = RentalHouse.objects.all()
district = request.query_params.get('district')
if district:
queryset = queryset.filter(district=district)
serializer = RentalHouseSerializer(queryset, many=True)
return Response(serializer.data)
对应URL配置:
python复制from django.urls import path
from .views import RentalListAPI
urlpatterns = [
path('api/rentals/', RentalListAPI.as_view(), name='rental-list'),
]
5. 数据可视化实现
5.1 ECharts集成
在Django模板中使用ECharts的典型方式:
html复制<div id="price-trend-chart" style="width: 100%; height: 400px;"></div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script>
var chartDom = document.getElementById('price-trend-chart');
var myChart = echarts.init(chartDom);
fetch('/api/price-trend/')
.then(response => response.json())
.then(data => {
var option = {
title: { text: '各行政区租金趋势' },
tooltip: { trigger: 'axis' },
legend: { data: data.districts },
xAxis: { type: 'category', data: data.months },
yAxis: { type: 'value' },
series: data.series
};
myChart.setOption(option);
});
</script>
5.2 典型可视化场景
-
价格分布直方图:
- 展示不同价格区间的房源数量
- 添加刷选交互功能
-
地理热力图:
- 基于行政区或商圈展示房源密度
- 结合颜色深浅表示平均价格
-
聚类结果散点图:
- 以面积和价格为轴展示聚类结果
- 不同颜色代表不同簇
-
时间趋势图:
- 展示各区域租金随时间变化趋势
- 支持多区域对比
6. 项目部署与优化
6.1 生产环境部署
推荐使用Docker容器化部署:
dockerfile复制# Dockerfile
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "rental_analysis.wsgi:application"]
配套的docker-compose.yml:
yaml复制version: '3'
services:
web:
build: .
ports:
- "8000:8000"
depends_on:
- redis
- db
environment:
- DJANGO_SETTINGS_MODULE=rental_analysis.settings.production
redis:
image: redis:alpine
ports:
- "6379:6379"
db:
image: postgres:13
environment:
- POSTGRES_DB=rental
- POSTGRES_USER=rental
- POSTGRES_PASSWORD=rental123
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
6.2 性能优化技巧
-
数据库优化:
- 添加适当的索引
- 使用select_related/prefetch_related减少查询次数
- 考虑使用Django的缓存框架
-
爬虫优化:
- 设置合理的下载延迟
- 使用Rotating Proxy防止封禁
- 实现增量爬取机制
-
前端优化:
- 使用Django的静态文件压缩
- 实现懒加载图表
- 添加数据缓存机制
7. 常见问题与解决方案
7.1 Scrapy爬虫被封锁
现象:爬虫运行一段时间后无法获取数据或返回403错误
解决方案:
- 设置随机User-Agent:
python复制# settings.py
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
# 添加多个常见浏览器UA
]
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
'scrapy_useragents.downloadermiddlewares.useragents.UserAgentsMiddleware': 500,
}
- 使用代理IP池:
python复制class ProxyMiddleware:
def process_request(self, request, spider):
request.meta['proxy'] = "http://your-proxy-ip:port"
7.2 聚类结果不理想
现象:聚类后的房源群体区分不明显或不符合业务预期
优化方向:
- 尝试不同的特征组合
- 调整特征缩放方法
- 使用轮廓系数评估聚类质量
- 考虑层次聚类等其他算法
7.3 Django性能瓶颈
现象:数据量大时页面加载缓慢
优化方案:
- 添加数据库索引:
python复制class Meta:
indexes = [
models.Index(fields=['price']),
models.Index(fields=['district', 'price']),
]
- 实现分页查询:
python复制from django.core.paginator import Paginator
def rental_list(request):
page_number = request.GET.get('page', 1)
paginator = Paginator(RentalHouse.objects.all(), 20)
page_obj = paginator.get_page(page_number)
return render(request, 'list.html', {'page_obj': page_obj})
- 使用Django Debug Toolbar分析性能瓶颈
8. 项目扩展方向
8.1 功能扩展建议
-
用户行为分析:
- 记录用户的搜索和浏览行为
- 实现个性化推荐
-
市场预警系统:
- 监测异常价格波动
- 识别潜在欺诈房源
-
移动端适配:
- 开发响应式前端
- 构建小程序版本
8.2 技术深化方向
-
算法优化:
- 尝试集成更多机器学习算法
- 实现模型在线学习
-
实时数据处理:
- 引入Kafka处理实时数据流
- 构建实时价格监控看板
-
微服务架构:
- 将爬虫、分析、API拆分为独立服务
- 使用Kubernetes管理容器
在实际开发这类系统时,有几个关键经验值得分享:首先,数据质量比算法复杂度更重要,建议在数据清洗阶段投入足够精力;其次,可视化设计要遵循"少即是多"原则,避免过度复杂的图表干扰信息传达;最后,系统架构要预留扩展空间,因为租房市场的分析需求会不断变化
