毕业设计:基于python热门旅游景点监控平台 数据分析系统 景点客流量统计 车流量统计 可视化 Flask框架 源码✅

博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

点击查看作者主页,了解更多项目!

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅

2、最全计算机专业毕业设计选题大全(建议收藏)✅

1、项目介绍

技术栈:
Python语言、Flask框架、MySQL数据库、Echarts可视化、HTML

2、项目界面

(1)旅游景点展示、景点热度、等级数量
在这里插入图片描述

(2)旅游监控平台

在这里插入图片描述

(3)旅游监控视频、景点客流量统计、车流量统计
在这里插入图片描述

(4)旅游监控视频、景点客流量统计、车流量统计
在这里插入图片描述

(5)景点详情信息

在这里插入图片描述

3、项目说明

这个基于Python、Flask框架、MySQL数据库、Echarts可视化和HTML技术的旅游监控与分析系统的功能模块可以描述如下:

  1. 旅游景点展示模块
    功能描述:该模块负责展示旅游景点的基本信息,包括景点名称、热度排名、等级数量等。通过直观的界面,用户可以快速了解各个景点的概况。
    界面元素:包含景点列表、热度排名、等级分布等图表或列表,可能使用Echarts等可视化工具进行展示。
  2. 旅游监控平台模块
    功能描述:该模块是系统的核心部分,负责实时监控旅游景点的各项数据,包括监控视频、景点客流量统计、车流量统计等。通过该模块,用户可以实时掌握景点的运营状况,及时做出响应。
    界面元素:包含实时监控视频窗口、客流量统计图表、车流量统计图表等。监控视频可能通过HTML5的video标签或第三方视频播放器进行展示,统计图表则可能使用Echarts等可视化工具进行绘制。
  3. 数据统计与分析模块
    功能描述(隐含):虽然具体界面未直接展示,但考虑到系统的实用性,该模块负责收集和分析旅游景点的各项数据,生成各类统计报表和分析报告。这些数据可以用于评估景点的运营效果、预测未来的旅游趋势等。
    技术实现:可能使用Python的pandas、numpy等库进行数据处理和分析,MySQL数据库用于存储和管理数据。Flask框架作为后端服务器,提供数据接口和页面渲染服务。
  4. 景点详情信息模块
    功能描述:该模块提供具体景点的详细信息,包括景点的历史背景、游览路线、开放时间、门票价格等。用户可以通过该模块深入了解感兴趣的景点。
    界面元素:可能包含文本描述、图片展示、视频介绍等多媒体元素,以及交互式地图或导航工具,帮助用户更好地规划行程。
  5. 用户交互与管理模块
    功能描述(隐含):该模块负责处理用户与系统之间的交互,包括用户登录、权限管理、数据查询与导出等功能。同时,该模块还可能包含系统管理员对系统的配置和维护功能。
    界面元素:可能包含登录/注册页面、权限管理页面、数据查询与导出页面等。这些页面通常设计得简洁明了,方便用户快速上手。

4、核心代码


from flask import Flask, render_template, json, request, redirect, url_for, make_response, session
import random, re

# from scripts.sql import SQL

import pymysql

class SQL:

    def __init__(self):
        self.host = 'localhost'
        self.username = 'root'
        self.password = '123456'
        self.database = 'zhihuilvyou'
        self.conn = None
        self.cursor = None

    def connect(self):
        self.conn = pymysql.connect(host=self.host, port=3306,user=self.username, password=self.password, database=self.database)

    def execute(self, str):
        if self.conn is None:
            self.connect()
        self.cursor = self.conn.cursor()
        self.cursor.execute(str)
        self.conn.commit()

    def query(self, str):
        if self.conn is None:
            self.connect()
        self.cursor = self.conn.cursor()
        self.cursor.execute(str)
        return self.cursor.fetchall()

    def close(self):
        self.cursor.close()
        self.conn.close()

# 生成flask实例,__name__指代的是当前文件名
app = Flask(__name__)

# secret_key签名加密的 sessionId ,sessionId保存在用户的cookie处,但是如果没有密钥就无法修改它
app.secret_key = b'CvH*89A4XuP3Ee&is4%'

# 访问根路径,即127.0.0.1/ ,就会自动执行下面定义的函数。请求方式可以有get和post,浏览器能直接发起的请求只有get请求,其余形式的请求(get,post,put,patch,delete)只能通过js脚本发起
@app.route('/', methods=["GET", "POST"])
def login():
    # 查看session是否有username值,浏览器传过来的sessionid不同,从服务器的session对象从拿到的数据也不同。如果能拿到username值,证明sessionid是正确的,即携带这个sessionid的浏览器是之前成功登录过的
    if 'username' in session:
        # redirect 重定向;url_for以视图函数名作为参数,返回对应的 URL。如 url_for('scanboard') 相当于 http://127.0.0.1/scanboard
        return redirect(url_for('scanboard'))

    # 如果请求方式是post请求
    if request.method == 'POST':
        # login_flag 变量用来标记是否是登录成功的,默认为false,登录成功则改变状态
        login_flag = False
        # 生成sql实例
        sql = SQL()
        # 查询所有用户名和秘密,存放到users_list变量里
        users_list = sql.query('select name, password from user;')
        # 浏览器向这个路径发送了json格式的数据,类似{"name":"用户名","password":"用户的密码"},下面两行分别提取name和password字段
        name = request.json['name']
        password = request.json['password']
        # 遍历数据库中查询到的数据,user的格式 ["数据库某用户名","数据库某密码"] ,一一比对浏览器发来的用户名密码和数据库的用户名密码,两个都完全符合,则改变login_flag为true
        for user in users_list:
            if user[0] == name and user[1] == password:
                login_flag = True
        # 如果login_flag为true,即提交的用户名密码和数据库中某一个用户的相同,返回给浏览器一个json格式的响应数据(选用json是因为方便前端解析和使用,现在前后端交互大多采用json)
        if login_flag:
            session['username'] = name
            return {"code": 200, "msg": "成功"}
        # 关闭数据库连接(因为数据库连接会一直占用内存,一个请求结束应当释放对应的连接)
        sql.close()
        # 如果login_flag为false,返回响应数据 用户名或密码错误
        return {"code": "401", "msg": "用户名或密码错误"}
    # 如果没有登录,且不是post请求,则返回登录页面文件
    return render_template('login.html')


@app.route('/scanboard')
def scanboard():
    if 'username' in session:
        sql = SQL()
        # 如果用户是登录过的,从accident景区事故表中选取所有的标题内容,保存到accident_tuple变量
        accident_tuple = sql.query('select title, content from accident;');
        sql.close()
        # accident_tuple=accident_tuple,将accident_tuple传递给scanboard.html文件,在scanboard.html文件中变量的名字也叫accident_tuple
        return render_template('scanboard.html', accident_tuple=accident_tuple)
    # 如果没有登录,重定向到登录页面
    return redirect(url_for("login"))


@app.route('/tourist')
def tourist():
    # 返回tourist.html文件
    return render_template('tourist.html')


@app.route('/scenery', methods=["GET", "POST"])
def scenery():
    if request.method == "GET":
        sql = SQL()
        # 从tb_sichuan_scenic表中查询所有字段,存放到scenery_tuple变量中
        scenery_tuple = sql.query(
            'select level, name, city, xian, address, lon, lat from tb_sichuan_scenic order by id desc;')
        # FiveStarPoints原本用了存放5A景点的所有信息,后来考虑5A景点太少,加入4A景点,变量名没改
        FiveStarPoints = []
        num = 0
        # value表示景区的热度值,5A景区初始值50,4A景区初始值40,然后再加一个0-50的随机数,避免地图景点热度数据单一
        for level, name, city, xian, address, lon, lat in scenery_tuple:
            if level == "5A" or level == "4A":
                value = 50 if level == "5A" else 40
                value = value + random.randint(0, 50)
                # 只选择5A、4A景区,调整成json的数据格式,存入FiveStarPoints列表中
                FiveStarPoints.append(
                    {"level": level, "name": name, "city": city, "xian": xian, "address": address, "lon": lon,
                     "lat": lat, "value": value})
                num = num + 1
            # 控制一下数据的数量,如果满100个数据就直接退出
            if num >= 100:
                break
        return render_template('scenery.html', FiveStarPoints=FiveStarPoints)
    if request.method == "POST":
        # 从前端页面传来的json数据中获取”name“值,name值为点击地图时获取的具体地点的名字,下面由于有几个州的名字和数据库的不一致,做了一下重新赋值
        name = request.json['name']
        if name == "阿坝藏族羌族自治州":
            name = "阿坝州"
        elif name == "甘孜藏族自治州":
            name = "甘孜州"
        elif name == "凉山彝族自治州":
            name = "凉山州"
        sql = SQL()
        # 查询tb_sichuan_scenic表中满足city=前端获取的name值的所有数据,比如前端点击成都市,这里会查询city=成都市的所有景点,将这些景点的所有数据查询存放到变量scenery_tuple中
        scenery_tuple = sql.query(
            'select level, name, city, xian, address, lon, lat from tb_sichuan_scenic where city = "%s" order by id desc;' % name)
        # scenery_list用于存放所有满足条件的景点的json数据
        scenery_list = []
        # 如果scenery_tuple有值,说明前端获取的name值是数据库中city的其中一项,前端echarts地图可以点击两种地方,1表示一个城市的地图块,2表示一个具体景点的亮点,这里scenery_tuple有值说明点击的是地图块
        if scenery_tuple:
            num = 0
            # star_level= [0,0,0,0,0],用于存放5A到1A景点的数量,下面的循环就是实现这个统计的
            star_level = [0] * 5
            for level, name, city, xian, address, lon, lat in scenery_tuple:
                if level == "5A":
                    star_level[0] = star_level[0] + 1
                if level == "4A":
                    star_level[1] = star_level[1] + 1
                if level == "3A":
                    star_level[2] = star_level[2] + 1
                if level == "2A":
                    star_level[3] = star_level[3] + 1
                if level == "1A":
                    star_level[4] = star_level[4] + 1

                # 将遍历出的景点信息调整成json格式存入scenery_list
                scenery_list.append(
                    {"level": level, "name": name, "city": city, "xian": xian, "address": address, "lon": lon,
                    "lat": lat})
                num = num + 1
                if num >= 100:
                    break
            # star_level存放景点等级信息,scenery_list存放满足条件的景点的详细信息,isCity可以取1或0,因为前端可能点击地图块或者景区亮点,点击不同类型的地方返回数据形式有差异,这里使用isCity字段作为区分的标志
            scenery_data = {"star_level": star_level, "scenery_list": scenery_list, "isCity": "1"}
        else:
            # 查询tb_sichuan_scenic,注意这里是name=前端获取的name值,前一个name是数据库查询tb_sichuan_scenic的name字段,即景区的名字。这个查询其实是上边查询city获取数据为空,说明前端点击的是具体的景点的那个亮点,
            # 所以这里查询name值获取这个景点的所有信息
            scenery_tuple = sql.query(
            'select level, name, city, xian, address, lon, lat from tb_sichuan_scenic where name = "%s" order by id desc;' % name)
            for level, name, city, xian, address, lon, lat in scenery_tuple:
                scenery_list.append(
                    {"level": level, "name": name, "city": city, "xian": xian, "address": address, "lon": lon,
                    "lat": lat})
            # 这里isCity值为0,标志返回数据不是城市的景点数据集,而是前端页面点击的具体景点的信息
            scenery_data = {"scenery_list": scenery_list, "isCity": "0"}
        sql.close()
        return scenery_data


@app.route('/evaluate', methods=["GET", "POST"])
def evaluate():
    if request.method == "GET":
        sql = SQL()
        chengdu_scenery = []
        scenery_tuple = sql.query('select star,score,sightId,intro,free,point,address,sightName,districts,qunarPrice,'
                                  'discount,sightImgURL from chengdu_scenery order by id asc;')
        for item in scenery_tuple:
            chengdu_scenery.append({
                "star": item[0],
                "score": item[1],
                "sightId": item[2],
                "intro": item[3],
                "free": item[4],
                "point": item[5],
                "address": item[6],
                "sightName": item[7],
                "districts": item[8],
                "qunarPrice": item[9],
                "discount": item[10],
                "sightImgURL": item[11]
            })
        scenery_evaluate = sql.query('select author, content, date, score from chengdu_scenery_evaluate where sightId = %s' % scenery_tuple[0][2])
        sql.close()
        return render_template('evaluate.html', chengdu_scenery=chengdu_scenery, scenery_evaluate=scenery_evaluate)

    if request.method == "POST":
        sql = SQL()
        sightId = request.json['sightId']
        evaluate = []
        try:
            evaluate_tuple = sql.query(
                'select author, content, date, score from chengdu_scenery_evaluate where sightId = %s' % sightId)
            if not evaluate_tuple:
                evaluate_tuple = sql.query('select author, content, date, score from chengdu_scenery_evaluate')
            evaluate_tuple = random.sample(evaluate_tuple, 20)
        except Exception as e:
            return "查询失败"

        for item in evaluate_tuple:
            evaluate.append({
                "author": item[0],
                "content": item[1],
                "date": item[2],
                "score": item[3]
            })
        sql.close()
        return {"evaluate": evaluate}


if __name__ == '__main__':
    app.run()

5、项目获取

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值