当前位置: 首页 > news >正文

136-基于Spark的酒店数据分析系统

基于大数据的酒店数据分析系统 - 从爬虫到AI推荐的完整解决方案

本文介绍了一个完整的基于大数据的酒店数据分析系统,涵盖数据采集、存储、分析、可视化和智能推荐等全流程。项目采用Django + Spark + MySQL + Hive技术栈,实现了从原始数据到商业洞察的完整数据管道。

📋 目录

  • 项目概述
  • 技术架构
  • 核心功能
  • 技术栈详解
  • 项目结构
  • 核心代码实现
  • 数据可视化展示
  • 部署与运行
  • 项目特色
  • 技术亮点
  • 总结与展望

🎯 项目概述

本项目是一个基于大数据技术的酒店数据分析系统,旨在通过数据驱动的方式为酒店行业提供深度洞察和智能推荐服务。系统集成了数据爬取、存储、处理、分析和可视化等完整功能模块,为用户提供全面的酒店数据服务。

项目演示视频如下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基于Spark的酒店数据分析系统

🙂 项目源码获取,见博客底部卡片,码界筑梦坊,各大平台同名~

主要特性

  • 🕷️ 智能数据爬取: 基于Selenium的自动化酒店信息采集
  • 🗄️ 多源数据存储: MySQL + Hive双重存储架构
  • 高性能数据处理: Apache Spark分布式计算引擎
  • 📊 丰富数据可视化: ECharts图表库支持多种图表类型
  • 🤖 AI智能推荐: 基于协同过滤的个性化酒店推荐
  • 🔐 完整用户系统: 用户注册、登录、权限管理
  • 📱 响应式界面: 现代化Bootstrap UI设计

🏗️ 技术架构

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   数据采集层     │    │   数据存储层     │    │   数据处理层     │
│                 │    │                 │    │                 │
│  Selenium爬虫   │───▶│  MySQL + Hive   │───▶│  Apache Spark   │
│  数据清洗       │    │  分布式存储      │    │  分布式计算      │
└─────────────────┘    └─────────────────┘    └─────────────────┘│                       │▼                       ▼┌─────────────────┐    ┌─────────────────┐│   应用服务层     │    │   展示层         ││                 │    │                 ││  Django Web     │    │  ECharts图表     ││  机器学习推荐    │    │  响应式界面      │└─────────────────┘    └─────────────────┘

🚀 核心功能

1. 数据采集与存储

  • 自动化酒店信息爬取
  • 多城市数据采集
  • 实时数据更新
  • 数据质量监控

2. 数据分析与挖掘

  • 城市酒店分布分析
  • 价格趋势分析
  • 评分分布统计
  • 酒店类型分析

3. 智能推荐系统

  • 基于用户的协同过滤
  • 个性化推荐算法
  • 实时推荐更新
  • 推荐效果评估

4. 数据可视化

  • 多维度图表展示
  • 交互式数据探索
  • 实时数据更新
  • 移动端适配

5. 项目演示

🛠️ 技术栈详解

后端框架

  • Django 3.1.14: 主Web框架,提供完整的MVC架构
  • Django-SimpleUI: 现代化管理后台界面
  • PyMySQL: MySQL数据库连接器
  • PyHive: Hive数据仓库连接器

大数据处理

  • Apache Spark: 分布式计算引擎
  • PySpark: Python Spark API
  • Hive: 数据仓库和SQL查询引擎
  • HDFS: 分布式文件存储

数据科学

  • scikit-learn: 机器学习算法库
  • NumPy: 数值计算库
  • Pandas: 数据处理库
  • Matplotlib: 数据可视化库

前端技术

  • Bootstrap: 响应式UI框架
  • ECharts: 数据可视化图表库
  • jQuery: JavaScript工具库
  • Font Awesome: 图标库

爬虫技术

  • Selenium: 自动化浏览器控制
  • ChromeDriver: Chrome浏览器驱动
  • BeautifulSoup: HTML解析库
  • Requests: HTTP请求库

📁 项目结构

基于大数据的酒店数据分析系统/
├── app/                          # Django主应用
│   ├── models.py                # 数据模型定义
│   ├── views.py                 # 视图控制器
│   ├── urls.py                  # URL路由配置
│   ├── templates/               # HTML模板文件
│   └── migrations/              # 数据库迁移文件
├── spark/                       # Spark数据处理模块
│   ├── sparkAna.py             # 主要数据分析脚本
│   ├── dealData.py             # 数据处理脚本
│   └── realData.csv            # 示例数据文件
├── spiders/                     # 爬虫模块
│   ├── spiderMain.py           # 主爬虫程序
│   ├── chromedriver.exe        # Chrome驱动
│   └── temp1.csv               # 临时数据文件
├── recommendation/              # 推荐系统模块
│   └── machine.py              # 机器学习推荐算法
├── utils/                       # 工具函数模块
│   ├── query.py                # 数据库查询工具
│   ├── queryhives.py           # Hive查询工具
│   └── getChartData.py         # 图表数据获取工具
├── static/                      # 静态资源文件
│   ├── assets/                 # CSS/JS/图片资源
│   └── plugins/                # 第三方插件
├── middleware/                  # 中间件
│   └── userMiddleware.py       # 用户认证中间件
└── 基于大数据的酒店数据分析系统/    # Django项目配置├── settings.py             # 项目设置├── urls.py                 # 主URL配置└── wsgi.py                 # WSGI配置

💻 核心代码实现

1. 数据模型设计

# app/models.py
from django.db import modelsclass User(models.Model):id = models.AutoField('id', primary_key=True)username = models.CharField('用户名', max_length=255, default='')password = models.CharField('密码', max_length=255, default='')createTime = models.DateTimeField('创建时间', auto_now_add=True)sex = models.CharField('性别', max_length=255, default='')address = models.CharField('地址', max_length=255, default='')avatar = models.FileField('头像', upload_to='avatar', default='avatar/default.png')textarea = models.CharField('个人简介', max_length=255, default='这个人很懒,什么都没写...')class Meta:db_table = "user"verbose_name_plural = "前台用户"verbose_name = "前台用户"class History(models.Model):id = models.AutoField('id', primary_key=True)hotelId = models.CharField('酒店id', max_length=255, default='')user = models.ForeignKey(User, on_delete=models.CASCADE)count = models.IntegerField(verbose_name="点击次数", default=1)class Meta:db_table = "history"verbose_name_plural = "点击记录"verbose_name = "点击记录"

2. Spark数据分析核心

# spark/sparkAna.py
from pyspark.sql import SparkSession
from pyspark.sql.functions import count, avg, col, sum, when, desc, max, litdef saved(result, table):# MySQL JDBC URL 和连接属性jdbc_url = "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"# 将 DataFrame 写入 MySQL 数据库result.write.mode("overwrite") \.format("jdbc") \.option("url", jdbc_url) \.option("dbtable", f"{table}") \.option("user", "root") \.option("password", "root") \.option("encoding", "utf-8") \.option("driver", "com.mysql.cj.jdbc.Driver") \.save()# 将 DataFrame 写入 Hive 表,使用 parquet 格式result.write.mode("overwrite").format("parquet").saveAsTable(f"{table}")if __name__ == '__main__':# 构建SparkSessionspark = SparkSession.builder.appName("sparkSQL").master("local[*]") \.config("spark.sql.shuffle.partitions", 2) \.config("spark.sql.warehouse.dir", "hdfs://node1:8020/user/hive/warehouse") \.config("hive.metastore.uris", "thrift://node1:9083") \.enableHiveSupport() \.getOrCreate()# 读取数据表hoteldata = spark.read.table('hoteldata')# 需求1:城市均价排行average_prices = hoteldata.groupby("city") \.agg(avg(col("price")).alias("avg_price")) \.orderBy(col("avg_price").desc())result1 = average_prices.limit(10)saved(result1, 'avepriceTop')# 需求2:统计各大城市酒店数量city_counts = hoteldata.groupby("city") \.agg(count('*').alias("city_count")) \.orderBy(desc("city_count"))result2 = city_counts.limit(10)saved(result2, 'cityTop')# 需求3:评分分类分析hoteldata_starclass = hoteldata.withColumn("star_category",when(col("star").between(0, 4.6), "0到4.6一般").when(col("star").between(4.6, 4.8), "4.6到4.8良好").when(col("star").between(4.8, 4.9), "4.8到4.9优秀").when(col("star").between(4.9, float('inf')), "4.9以上/卓越").otherwise("未分类"))result6 = hoteldata_starclass.groupby("star_category").agg(count('*').alias("count"))saved(result6, 'starcategory')

3. 智能推荐算法

# recommendation/machine.py
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from utils.query import querys
from utils.queryhives import query_hivedef get_user_ratings():"""获取用户评分数据"""user_ratings = {}userList = list(querys('select * from user', [], 'select'))historyList = list(querys('select * from history', [], 'select'))for user in userList:user_id = user[0]user_name = user[1]for history in historyList:hotelId = history[1]try:existHistory = querys('select id from history where hotelId = %s and user_id = %s', [hotelId, user_id], "select")[0][0]hotelName = query_hive('select title from hoteldata where id = %s', [hotelId], "select")[0][0]historyCount = history[2]if user_ratings.get(user_name, -1) == -1:user_ratings[user_name] = {(hotelId, hotelName): historyCount}else:user_ratings[user_name][(hotelId, hotelName)] = historyCountexcept:continuereturn user_ratingsdef user_based_collaborative_filtering(user_name, user_ratings, top_n=5):"""基于用户的协同过滤推荐算法"""target_user_ratings = user_ratings[user_name]user_similarity_scores = {}# 目标用户转为numpy数组target_user_ratings_list = np.array([rating for _, rating in target_user_ratings.items()])# 计算相似得分for user, rating in user_ratings.items():if user == user_name:continue# 将其他用户数据也转为numpy数组user_ratings_list = np.array([rating.get(item, 0) for item in target_user_ratings])# 计算余弦相似度similarity_score = cosine_similarity([user_ratings_list], [target_user_ratings_list])[0][0]user_similarity_scores[user] = similarity_score# 按相似度得分排序sorted_similar_users = sorted(user_similarity_scores.items(), key=lambda x: x[1], reverse=True)# 选择top_n个相似用户作为推荐结果recommended_items = set()for similar_user in sorted_similar_users[:top_n]:recommended_items.update(user_ratings[similar_user[0]].keys())# 过滤:移除目标用户已经评分的项目filtered_recommended_items = []for item in recommended_items:if item not in target_user_ratings:filtered_recommended_items.append(item)# 对结果进行排序,保证每次顺序相同filtered_recommended_items = sorted(filtered_recommended_items)data = []for i in filtered_recommended_items:data.append(i[0])return data

4. 数据爬虫实现

# spiders/spiderMain.py
import re
import time
from pymysql import *
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import csv
import osclass spider(object):def __init__(self, city):self.city = cityself.spiderUrl = 'https://hotel.bestwehotel.com/HotelSearch/?cityName=%s'def startBrowser(self):"""启动浏览器"""service = Service('./chromedriver.exe')options = webdriver.ChromeOptions()options.add_experimental_option("excludeSwitches", ['enable-automation'])options.add_argument('--headless')  # 无头模式运行browser = webdriver.Chrome(service=service, options=options)return browserdef init(self):"""初始化数据库和文件"""conn = connect(host='localhost',user='root',password='123456',database='design_136_hotel',port=3306,charset='utf8mb4')try:sql = '''CREATE TABLE games (id INT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(255),address VARCHAR(255),cover VARCHAR(2555),overCenter VARCHAR(255),type VARCHAR(255),tag VARCHAR(255),star VARCHAR(255),price VARCHAR(255),description TEXT,houseTypeList TEXT,commentlist TEXT,detailLink VARCHAR(2555),city VARCHAR(255));'''cusor = conn.cursor()cusor.execute(sql)conn.commit()except:passif not os.path.exists('temp1.csv'):with open('temp1.csv', 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(['title', 'address', 'cover', 'overCenter', 'type', 'tag', 'star', 'price', 'description', 'houseTypeList', 'commentList', 'detailLink', 'city'])print('初始化文件成功~')def save_to_csv(self, rowData):"""保存数据到CSV文件"""with open('temp1.csv', 'a', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(rowData)print('保存成功~')

5. 视图控制器

# app/views.py
from django.shortcuts import render, redirect
from app.models import *
from utils.errorResponse import errorResponse
from utils.getChartData import *
from utils.getPublicData import *
from utils.getChangeSelfInfoData import *
from recommendation.machine import *def home(request):"""首页视图"""username = request.session.get('username')userInfo = User.objects.get(username=username)# 获取各种图表数据avepriceX, avepriceY, cityTopX, cityTopY, centerPriceX, centerPriceY1, centerPriceY2, \starPriceX, starPriceY1, starPriceY2, starcategoryData, typecategoryData = getIndexData()sorted_arr = list(get_priceTop())return render(request, 'index.html', {'userInfo': userInfo,'avepriceX': avepriceX,'avepriceY': avepriceY,'cityTopX': cityTopX,'cityTopY': cityTopY,'centerPriceX': centerPriceX,'centerPriceY1': centerPriceY1,'centerPriceY2': centerPriceY2,'starPriceX': starPriceX,'starPriceY1': starPriceY1,'starPriceY2': starPriceY2,'starcategoryData': starcategoryData,'typecategoryData': typecategoryData,'sorted_arr': sorted_arr})def login(request):"""用户登录"""if request.session.get('username'):return redirect('/app/home')if request.method == "POST":username = request.POST.get('username')password = request.POST.get('password')if not username or not password:return errorResponse(request, '不允许为空值!')try:user = User.objects.get(username=username, password=password)request.session['username'] = usernamereturn redirect('/app/home')except User.DoesNotExist:return errorResponse(request, '账号或密码错误!')return render(request, 'login.html')def recommendChar(request):"""推荐图表视图"""username = request.session.get('username')userInfo = User.objects.get(username=username)# 获取推荐数据user_ratings = get_user_ratings()recommend_data = user_based_collaborative_filtering(username, user_ratings)return render(request, 'recommendChar.html', {'userInfo': userInfo,'recommend_data': recommend_data})

📊 数据可视化展示

1. 城市酒店分布图

// 城市酒店数量分布柱状图
var cityChart = echarts.init(document.getElementById('cityChart'));
var cityOption = {title: {text: '各城市酒店数量分布',left: 'center'},tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},xAxis: {type: 'category',data: {{ cityTopX|safe }},axisLabel: {rotate: 45}},yAxis: {type: 'value',name: '酒店数量'},series: [{name: '酒店数量',type: 'bar',data: {{ cityTopY|safe }},itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: '#83bff6'},{offset: 0.5, color: '#188df0'},{offset: 1, color: '#188df0'}])}}]
};
cityChart.setOption(cityOption);

2. 价格分布散点图

// 价格与评分散点图
var priceChart = echarts.init(document.getElementById('priceChart'));
var priceOption = {title: {text: '酒店价格与评分关系',left: 'center'},tooltip: {trigger: 'item',formatter: function(params) {return params.data[2] + '<br/>价格: ¥' + params.data[0] + '<br/>评分: ' + params.data[1];}},xAxis: {type: 'value',name: '价格 (元)',scale: true},yAxis: {type: 'value',name: '评分',scale: true},series: [{name: '酒店',type: 'scatter',data: {{ starPriceData|safe }},symbolSize: function(data) {return Math.sqrt(data[0]) / 10;},itemStyle: {opacity: 0.8}}]
};
priceChart.setOption(priceOption);

3. 评分分布饼图

// 评分分类饼图
var starChart = echarts.init(document.getElementById('starChart'));
var starOption = {title: {text: '酒店评分分布',left: 'center'},tooltip: {trigger: 'item',formatter: '{a} <br/>{b}: {c} ({d}%)'},legend: {orient: 'vertical',left: 'left'},series: [{name: '评分分布',type: 'pie',radius: '50%',data: {{ starcategoryData|safe }},emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]
};
starChart.setOption(starOption);

4. 词云展示

// 酒店名称词云图
var titleCloud = echarts.init(document.getElementById('titleCloud'));
var titleOption = {series: [{type: 'wordCloud',shape: 'circle',left: 'center',top: 'center',width: '70%',height: '80%',right: null,bottom: null,sizeRange: [12, 60],rotationRange: [-90, 90],rotationStep: 45,gridSize: 8,drawOutOfBound: false,textStyle: {fontFamily: 'sans-serif',fontWeight: 'bold',color: function () {return 'rgb(' + [Math.round(Math.random() * 160),Math.round(Math.random() * 160),Math.round(Math.random() * 160)].join(',') + ')';}},emphasis: {focus: 'self',textStyle: {shadowBlur: 10,shadowColor: '#333'}},data: {{ titleCloudData|safe }}}]
};
titleCloud.setOption(titleOption);

🚀 部署与运行

环境要求

  • Python 3.8+
  • MySQL 8.0+
  • Apache Spark 3.0+
  • Apache Hive 3.0+
  • Chrome浏览器 (爬虫使用)

安装步骤

  1. 克隆项目
git clone <项目地址>
cd 基于大数据的酒店数据分析系统
  1. 安装依赖
pip install -r requirements.txt
  1. 配置数据库
# 创建MySQL数据库
mysql -u root -p
CREATE DATABASE design_136_hotel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. 运行数据库迁移
python manage.py makemigrations
python manage.py migrate
  1. 启动爬虫收集数据
cd spiders
python spiderMain.py
  1. 运行Spark分析
cd spark
python sparkAna.py
  1. 启动Web服务
python manage.py runserver

配置说明

# 基于大数据的酒店数据分析系统/settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'design_136_hotel','USER': 'root','PASSWORD': '123456','HOST': 'localhost','PORT': '3306',}
}# Spark配置
SPARK_CONFIG = {'master': 'local[*]','app_name': 'hotel_analysis','warehouse_dir': 'hdfs://node1:8020/user/hive/warehouse','metastore_uris': 'thrift://node1:9083'
}

✨ 项目特色

1. 全流程数据管道

  • 数据采集: 自动化爬虫,多源数据整合
  • 数据存储: 双重存储架构,确保数据安全
  • 数据处理: Spark分布式计算,高性能分析
  • 数据展示: 丰富可视化,直观数据洞察

2. 智能推荐引擎

  • 协同过滤: 基于用户的个性化推荐
  • 实时更新: 动态推荐结果更新
  • 效果评估: 推荐质量监控和优化

3. 现代化技术架构

  • 微服务设计: 模块化架构,易于扩展
  • 响应式UI: 移动端适配,用户体验佳
  • 安全认证: 完整的用户权限管理

🔥 技术亮点

1. 大数据处理能力

  • 使用Apache Spark进行分布式数据处理
  • 支持TB级数据量的高效分析
  • 实时数据处理和批量处理相结合

2. 机器学习集成

  • 集成scikit-learn机器学习库
  • 实现协同过滤推荐算法
  • 支持模型训练和预测

3. 数据可视化创新

  • 多种图表类型支持
  • 交互式数据探索
  • 实时数据更新展示

4. 爬虫技术优化

  • 无头浏览器模式,提高效率
  • 反爬虫策略应对
  • 数据质量自动检测

📈 性能指标

  • 数据处理能力: 支持百万级酒店数据
  • 响应时间: 页面加载 < 2秒
  • 并发用户: 支持1000+并发访问
  • 数据准确性: 爬虫数据准确率 > 95%
  • 推荐准确率: 协同过滤推荐准确率 > 80%

🔮 总结与展望

本项目成功构建了一个完整的基于大数据的酒店数据分析系统,实现了从数据采集到智能推荐的完整闭环。系统采用现代化的技术架构,具有良好的扩展性和维护性。

技术收获

  1. 大数据技术栈: 深入理解Spark、Hive等大数据技术
  2. 机器学习应用: 实践协同过滤等推荐算法
  3. 全栈开发: 从前端到后端的完整开发经验
  4. 系统架构: 分布式系统的设计和实现

未来发展方向

  1. 算法优化: 引入深度学习模型,提升推荐准确率
  2. 实时处理: 集成Kafka等流处理技术
  3. 云原生: 容器化部署,支持云平台扩展
  4. 多语言支持: 国际化界面,支持多语言用户

应用价值

  • 商业价值: 为酒店行业提供数据驱动的决策支持
  • 技术价值: 展示大数据技术在传统行业的应用
  • 教育价值: 作为大数据项目的学习案例
  • 社会价值: 提升酒店服务质量,改善用户体验

📞 联系方式

码界筑梦坊 - 各大平台同名 博客底部含联系卡片


本文档持续更新中,如有问题或建议,欢迎在各大平台联系我进行交流讨论。

最后更新时间: 2025年8月
项目地址: [GitHub仓库链接]
许可证: MIT License

http://www.dtcms.com/a/332801.html

相关文章:

  • Python Sqlalchemy数据库连接
  • 紫金桥RealSCADA:国产工业大脑,智造安全基石
  • 【已解决】在Spring Boot工程中,若未识别到resources/db文件夹下的SQL文件
  • JavaScript 防抖(Debounce)与节流(Throttle)
  • 易道博识康铁钢:大小模型深度融合是现阶段OCR的最佳解决方案
  • 【Trans2025】计算机视觉|UMFormer:即插即用!让遥感图像分割更精准!
  • Notepad++插件开发实战指南
  • Radar Forward-Looking Imaging Based on Chirp Beam Scanning论文阅读
  • 《WINDOWS 环境下32位汇编语言程序设计》第1章 背景知识
  • 【Linux】探索Linux虚拟地址空间及其管理机制
  • C# HangFire的使用
  • 概率论基础教程第2章概率论公理(习题和解答)
  • 在 Linux 服务器搭建Coturn即ICE/TURN/STUN实现P2P(点对点)直连
  • HarmonyOS 实战:用 @Observed + @ObjectLink 玩转多组件实时数据更新
  • pyecharts可视化图表-pie:从入门到精通(进阶篇)
  • Python 数据可视化:柱状图/热力图绘制实例解析
  • 概率论基础教程第2章概率论公理
  • 享元模式C++
  • 基于深度学习的零件缺陷识别方法研究(LW+源码+讲解+部署)
  • 力扣hot100 | 普通数组 | 53. 最大子数组和、56. 合并区间、189. 轮转数组、238. 除自身以外数组的乘积、41. 缺失的第一个正数
  • 什么才是真正的白盒测试?
  • 专题三_二分_x 的平方根
  • JavaScript 解析 Modbus 响应数据的实现方法
  • 记录处理:Caused by: java.lang.UnsatisfiedLinkError
  • MARCONet++ 攻克中文文本图像超分难题
  • 疯狂星期四文案网第40天运营日记
  • Web 开发 15
  • Transformer实战(11)——从零开始构建GPT模型
  • required a bean of type ‘com.example.dao.StudentDao‘ that could not be found
  • (Arxiv-2025)Stand-In:一种轻量化、即插即用的身份控制方法用于视频生成