Python广东省可视化租房推荐系统
·
广东省租房可视化与推荐系统:基于Django的全栈开发实践
摘要
本文详细介绍了一个基于Python的web框架(Django)开发的广东省租房可视化与推荐系统的完整开发过程。系统集成了数据爬取、可视化分析、个性化推荐等核心功能,为租房用户提供全面的信息服务。
第一章:项目背景与需求分析
1.1 项目背景
随着广东省城市化进程的加快,租房市场需求日益增长。传统租房平台存在信息分散、数据分析不足、推荐不精准等问题。本项目旨在构建一个集数据采集、可视化分析和智能推荐于一体的综合性租房平台。
1.2 核心需求
- 数据采集需求:实时获取广东省主要城市的租房信息
- 可视化需求:提供多维度全方位的数据可视化动态图表分析
- 推荐需求:基于用户行为实现个性化房源推荐
- 用户体验需求:简洁直观的界面设计和流畅的交互体验
第二章:技术选型与系统架构
2.1 技术栈选择
后端技术
- 框架:Django 5.2.11
- 数据库:MySQL 8.0+
- ORM:Django内置ORM(用户直接对数据库操作)
前端技术
- UI框架:Bootstrap 5
- 可视化库:ECharts
- 模板引擎:Django模板
- JavaScript:原生JS + jQuery
爬虫技术
- 请求库:Requests
- 解析库:lxml
- 数据存储:CSV + MySQL双存储
2.2 系统架构设计
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 数据采集层 │ │ 业务逻辑层 │ │ 表现层 │
│ - 网络爬虫 │───▶│ - Django视图 │───▶│ - 前端模板 │
│ - 数据清洗 │ │ - 推荐算法 │ │ - 可视化图表 │
│ - 数据存储 │ │ - 业务逻辑 │ │ - 用户界面 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 数据存储层 │ │ 服务层 │ │ 客户端 │
│ - MySQL数据库 │ │ - Web服务器 │ │ - 浏览器 │
│ - 静态文件 │ │ - 缓存服务 │ │ - 移动设备 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
第三章:数据库设计与实现
3.1 核心数据模型
用户表(User)
class User(models.Model):
id = models.AutoField('id', primary_key=True)
username = models.CharField(verbose_name="姓名", max_length=22)
password = models.CharField(verbose_name="密码", max_length=32)
phone = models.CharField(verbose_name="手机号", max_length=11)
email = models.CharField(verbose_name="邮箱", max_length=22)
time = models.DateField(verbose_name="创建时间", auto_now_add=True)
avatar = models.FileField(verbose_name="头像", upload_to="user/")
房源表(Rental)
class Rental(models.Model):
title = models.CharField(max_length=255, verbose_name='标题')
type = models.CharField(max_length=50, verbose_name='类型')
layout = models.CharField(max_length=50, verbose_name='布局')
orientation = models.CharField(max_length=50, verbose_name='朝向')
city = models.CharField(max_length=50, verbose_name='城市')
district = models.CharField(max_length=50, verbose_name='行政区')
street = models.CharField(max_length=100, verbose_name='街道')
area = models.FloatField(verbose_name='面积')
price = models.IntegerField(verbose_name='价格')
tags = models.TextField(verbose_name='标签')
detail = models.TextField(verbose_name='详情')
imgs = models.TextField(verbose_name='图片链接')
oid = models.CharField(unique=True, max_length=100, verbose_name='房源ID')
用户行为表
# 浏览历史表
class BrowseHistory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
house = models.ForeignKey(Rental, on_delete=models.CASCADE)
browse_time = models.DateTimeField('浏览时间', auto_now_add=True)
# 用户收藏表
class Favorites(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
house = models.ForeignKey(Rental, on_delete=models.CASCADE)
count = models.IntegerField("点击次数", default=1)
第四章:数据采集模块实现
4.1 爬虫架构设计
爬虫工作流程
4.2 核心爬虫代码
import requests
from lxml import etree
import csv
import time
class LianjiaSpider:
def __init__(self):
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'cookie': '完整的cookie信息'
}
self.base_url = 'https://zh.lianjia.com/zufang/pg{}/#contentList'
def crawl_data(self, start_page=1, end_page=50):
"""主爬取函数"""
for page in range(start_page, end_page + 1):
url = self.base_url.format(page)
try:
response = requests.get(url, headers=self.headers)
html = etree.HTML(response.text)
self.parse_page(html, page)
time.sleep(2) # 延时防止被封
except Exception as e:
print(f"第{page}页爬取失败: {e}")
def parse_page(self, html, page_num):
"""解析单页数据"""
house_list = html.xpath('//div[@class="content__list"]/div')
with open('guangdong_house.csv', 'a+', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
for house in house_list:
try:
# 提取房源详细信息
title_info = house.xpath('.//a[@class="twoline"]/text()')[0].strip().split()
data = {
'title': title_info[0].split('·')[-1],
'type': title_info[0].split('·')[0],
'layout': title_info[1],
'orientation': title_info[2],
'city': '珠海市',
'district': house.xpath('.//p[@class="content__list--item--des"]/a/text()')[0],
'street': house.xpath('.//p[@class="content__list--item--des"]/a/text()')[1],
'area': house.xpath('.//p[@class="content__list--item--des"]/text()')[4].strip(),
'price': house.xpath('.//span[@class="content__list--item-price"]/em/text()')[0],
'tags': house.xpath('.//p[@class="content__list--item--bottom oneline"]/i/text()'),
'detail_url': 'https://hz.lianjia.com/' + house.xpath('.//a[@class="content__list--item--aside"]/@href')[0],
'image_url': house.xpath('.//a[@class="content__list--item--aside"]/img/@data-src')[0]
}
# 写入CSV文件
writer.writerow(list(data.values()))
except Exception as e:
print(f"解析房源信息失败: {e}")
4.3 数据清洗与处理
数据清洗策略
- 缺失值处理:删除关键信息缺失的记录
- 格式统一:统一价格、面积等数值格式
- 去重处理:基于房源ID去除重复记录
- 异常值检测:识别并处理异常价格和面积数据
第五章:数据可视化模块
5.1 可视化架构设计
可视化组件分类
- 统计图表:柱状图、饼图、折线图
- 地理信息:热力图、分布图
- 文本分析:词云图、标签云
- 交互组件:筛选器、排序器
5.2 ECharts集成实现
价格分布可视化
// 价格区间分布图
function renderPriceDistribution(data) {
const chart = echarts.init(document.getElementById('price-chart'));
const option = {
title: { text: '房源价格分布' },
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: ['0-1000', '1000-2000', '2000-3000', '3000-5000', '5000+']
},
yAxis: { type: 'value' },
series: [{
data: data,
type: 'bar',
itemStyle: { color: '#5470c6' }
}]
};
chart.setOption(option);
}
地理分布热力图
// 城市房源分布热力图
function renderCityHeatMap(data) {
const chart = echarts.init(document.getElementById('city-map'));
const option = {
title: { text: '广东省各城市房源分布' },
tooltip: { trigger: 'item' },
visualMap: {
min: 0,
max: Math.max(...data.map(item => item.value)),
calculable: true,
inRange: { color: ['#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#fee090', '#fdae61', '#f46d43', '#d73027'] }
},
series: [{
type: 'heatmap',
coordinateSystem: 'geo',
data: data
}]
};
chart.setOption(option);
}
5.3 实时数据更新机制
数据更新策略
- 定时刷新:设置定时器定期更新数据
- 事件驱动:用户操作触发数据更新
- 增量更新:只更新变化的数据部分
- 缓存机制:合理使用缓存减少服务器压力
第六章:推荐算法实现
6.1 推荐系统架构
推荐算法分类
- 基于内容的推荐:房源特征相似度匹配
- 协同过滤推荐:用户行为模式分析
- 混合推荐:多种算法结果融合
- 热门推荐:基于流行度的推荐
6.2 核心推荐算法
基于内容的推荐
def content_based_recommendation(user_preferences, house_features, top_n=10):
"""基于内容的房源推荐"""
# 计算房源与用户偏好的相似度
similarities = []
for house in house_features:
similarity = calculate_similarity(user_preferences, house)
similarities.append((house['id'], similarity))
# 按相似度排序并返回前N个
similarities.sort(key=lambda x: x[1], reverse=True)
return [item[0] for item in similarities[:top_n]]
def calculate_similarity(preferences, features):
"""计算相似度"""
# 使用余弦相似度或欧几里得距离
# 考虑价格、面积、位置、户型等多个维度
pass
协同过滤推荐
def collaborative_filtering(user_id, top_n=10):
"""基于用户的协同过滤推荐"""
# 获取目标用户的浏览历史
target_history = get_user_browse_history(user_id)
# 找到相似用户
similar_users = find_similar_users(user_id)
# 基于相似用户的行为推荐房源
recommendations = []
for similar_user in similar_users:
user_history = get_user_browse_history(similar_user.id)
# 推荐目标用户未浏览过的房源
new_houses = set(user_history) - set(target_history)
recommendations.extend(new_houses)
return recommendations[:top_n]
截图

















结语
广东省租房可视化与推荐系统是一个功能完整、技术先进的全栈Web应用项目。通过本项目的开发实践,我们不仅掌握了Django全栈开发的技术要点,还深入理解了数据采集、可视化分析和推荐算法的实际应用。
本项目为租房市场的数字化转型提供了有益参考,也为类似项目的开发积累了宝贵经验。未来,我们将继续优化系统性能,扩展功能模块,为用户提供更优质的租房信息服务。
最后需要该项目的同学可以私信我或者添加我下方名片获取!
更多推荐


所有评论(0)