1. 项目概述
这个基于去哪儿网数据的旅游推荐系统,是我去年指导计算机专业学生完成的毕业设计项目。系统整合了网络爬虫、数据可视化、推荐算法等多项技术,实现了从数据采集到智能推荐的完整流程。对于想要学习Python全栈开发、数据分析和推荐系统原理的同学来说,这个项目具有很好的参考价值。
系统核心功能包括:
- 使用Requests爬虫获取去哪儿网旅游数据
- Django框架搭建Web应用
- 协同过滤算法实现个性化推荐
- ECharts数据可视化展示
- 用户行为分析和热门景点挖掘
2. 系统架构设计
2.1 技术选型分析
后端框架选择Django的原因:
- 自带ORM和Admin后台,适合快速开发数据密集型应用
- 完善的模板系统便于前后端数据交互
- 丰富的第三方库支持(如Django-rest-framework)
- 自带用户认证系统,简化开发流程
爬虫技术选型:
- Requests + BeautifulSoup组合
- 相比Scrapy更轻量级
- 适合定向抓取结构化数据
- 配合随机User-Agent和IP代理池解决反爬
2.2 数据流程设计
系统数据处理流程分为四个阶段:
数据采集层:
- 定时爬取去哪儿网景点数据
- 存储到MySQL数据库
- 数据清洗和格式化
数据处理层:
- 用户行为数据分析
- 景点特征提取
- 数据标准化处理
算法层:
- 基于用户的协同过滤算法
- 基于内容的推荐算法
- 混合推荐策略
应用层:
- Web界面展示
- 交互式可视化
- 推荐结果呈现
3. 核心功能实现
3.1 数据爬取模块
def get_scenic_spots(city): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...', 'Referer': 'https://www.qunar.com/' } url = f'https://piao.qunar.com/ticket/list.htm?keyword={city}' try: response = requests.get(url, headers=headers, timeout=10) soup = BeautifulSoup(response.text, 'html.parser') # 解析景点数据 spots = [] items = soup.select('.sight_item') for item in items: name = item.select_one('.name').text.strip() price = item.select_one('.sight_item_price em').text # 其他字段解析... spots.append({'name':name, 'price':price}) return spots except Exception as e: print(f"爬取失败: {str(e)}") return []爬虫注意事项:
- 设置合理的请求间隔(建议3-5秒)
- 使用代理IP池轮换
- 模拟正常用户行为(随机滑动、点击等)
- 处理各种异常情况(超时、解析失败等)
3.2 推荐算法实现
协同过滤算法核心步骤:
- 构建用户-景点评分矩阵
- 计算用户相似度(余弦相似度)
- 预测目标用户对未评分景点的偏好
- 生成TOP-N推荐列表
from sklearn.metrics.pairwise import cosine_similarity def user_based_cf(user_id, n_recommend=5): # 获取用户-景点评分矩阵 rating_matrix = get_rating_matrix() # 计算用户相似度 user_sim = cosine_similarity(rating_matrix) # 获取相似用户 similar_users = np.argsort(user_sim[user_id])[::-1][1:11] # 预测评分 pred_ratings = [] for item in unrated_items: weighted_sum = 0 sim_sum = 0 for u in similar_users: if rating_matrix[u, item] > 0: weighted_sum += user_sim[user_id, u] * rating_matrix[u, item] sim_sum += user_sim[user_id, u] if sim_sum > 0: pred_ratings.append((item, weighted_sum/sim_sum)) # 返回TopN推荐 return sorted(pred_ratings, key=lambda x: x[1], reverse=True)[:n_recommend]3.3 可视化展示
使用ECharts实现的数据看板包含:
- 景点评分分布雷达图
- 热门城市景点数量柱状图
- 用户偏好词云
- 价格区间分布饼图
// 示例:景点评分雷达图 option = { title: { text: '景点评分维度分析' }, radar: { indicator: [ { name: '风景', max: 5 }, { name: '服务', max: 5 }, { name: '交通', max: 5 }, { name: '性价比', max: 5 }, { name: '设施', max: 5 } ] }, series: [{ type: 'radar', data: [ { value: [4.2, 3.8, 4.0, 3.5, 3.9], name: '西湖' }, { value: [4.5, 4.1, 3.7, 4.0, 4.2], name: '故宫' } ] }] };4. 系统部署与优化
4.1 性能优化方案
数据库优化:
- 为常用查询字段建立索引
- 使用Redis缓存热门推荐结果
- 定期归档历史数据
算法优化:
- 采用增量计算更新用户相似度
- 使用矩阵分解降维
- 实现离线批量计算+实时推荐结合
前端优化:
- 使用CDN加载静态资源
- 实现懒加载和分页
- 压缩图片和JS/CSS文件
4.2 部署方案
生产环境部署建议:
- Nginx + uWSGI + Django
- MySQL主从复制
- Redis缓存服务器
- 独立爬虫服务器
- 使用Supervisor管理进程
5. 常见问题与解决方案
5.1 爬虫被封禁问题
现象:请求返回403状态码或验证码页面
解决方案:
- 降低请求频率(控制在3-5秒/次)
- 使用高质量代理IP
- 随机化User-Agent
- 模拟鼠标移动和点击行为
- 设置合理的超时和重试机制
5.2 冷启动问题
现象:新用户/新景点缺乏历史数据,推荐效果差
解决方案:
- 混合推荐策略(协同过滤+基于内容)
- 利用热门景点作为默认推荐
- 收集用户注册时的偏好信息
- 采用基于知识的推荐方法
5.3 推荐多样性不足
现象:推荐结果过于集中,缺乏惊喜度
改进方法:
- 引入随机扰动因子
- 混合不同类型推荐结果
- 基于场景和时间的动态权重调整
- 采用多样性重排序算法
6. 项目扩展方向
在实际开发中,我们还尝试了以下扩展功能:
- 情感分析:对景点评论进行情感倾向分析
- 路线规划:结合地图API提供旅游路线建议
- 价格预测:基于历史数据的门票价格波动预测
- 实时推荐:结合用户实时行为调整推荐结果
这个项目完整展示了从数据采集到智能推荐的完整流程,涉及的技术栈广泛但又不失深度。对于计算机专业的学生来说,通过实现这样一个系统可以全面锻炼编程能力、算法理解能力和工程实践能力。