小言_互联网的博客

基于Flask+Echarts+爬虫的疫情监控系统

268人阅读  评论(0)

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:项目🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥

🍎前言

今天是1024,一个特殊的日子,发一个小项目吧!也意味着我要开始写项目专栏好了,陆陆续续会将之前写的项目总结到博客中,因为属实拖得有点久了,本次的项目是基于flask+echarts的疫情监控系统!

🍓开发目的及意义

全球Covid-19大危机影响我们的生活,我们的出行、交流、教育、经济等都发生了巨大的变化,全球疫情大数据可视化分析与展示,可用于社会各界接入疫情数据,感知疫情相关情况的实时交互式态势,是重要的疫情分析、防控决策依据。并且随着疫情的持久化,难免会有很多人会产生懈怠,因此我觉得做一个疫情数据的大屏可视化展示来提示人们显得十分重要,此大屏项目可以展示在一些大型公共场所,单位,学校,还是比较有用的!

🍓项目涉及技术

  • Flask
  • Echarts
  • mysql
  • 爬虫
  • 前端三件套

🍓项目主要流程

由python编写网络爬虫获取相应的疫情数据并保存到mysql数据库,由flask搭建web项目,用echarts进行数据展示!

🍓项目数据的爬取

关于本项目的所需数据我已在之前总结成博客,请看这两篇博文:
👉爬取疫情数据并存到mysql数据库
👉获取疫情资讯数据

🍓项目数据库设计

🍅ER图

🍅建表SQL

-- ----------------------------
-- Table structure for details
-- ----------------------------
DROP TABLE IF EXISTS `details`;
CREATE TABLE `details`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '数据最后更新时间',
  `province` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '省',
  `city` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '市',
  `confirm` int(0) NULL DEFAULT NULL COMMENT '累计确诊',
  `now_confirm` int(0) NULL DEFAULT NULL COMMENT '现有确诊',
  `confirm_add` int(0) NULL DEFAULT NULL COMMENT '新增确诊',
  `wzz_add` int(0) NULL DEFAULT NULL COMMENT '新增无症状',
  `heal` int(0) NULL DEFAULT NULL COMMENT '累计治愈',
  `dead` int(0) NULL DEFAULT NULL COMMENT '累计死亡',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 518 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for event
-- ----------------------------
DROP TABLE IF EXISTS `event`;
CREATE TABLE `event`  (
  `event_time` datetime(0) NOT NULL COMMENT '日期',
  `event_description` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '事件',
  PRIMARY KEY (`event_time`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for history
-- ----------------------------
DROP TABLE IF EXISTS `history`;
CREATE TABLE `history`  (
  `ds` datetime(0) NOT NULL COMMENT '日期',
  `confirm` int(0) NULL DEFAULT NULL COMMENT '累计确诊',
  `confirm_add` int(0) NULL DEFAULT NULL COMMENT '当日新增确诊',
  `local_confirm` int(0) NULL DEFAULT NULL COMMENT '现有本土确诊',
  `local_confirm_add` int(0) NULL DEFAULT NULL COMMENT '本土当日新增确诊',
  `local_no_infect` int(0) NULL DEFAULT NULL COMMENT '现有本土无症状',
  `local_no_infect_add` int(0) NULL DEFAULT NULL COMMENT '本土当日新增无症状',
  `heal` int(0) NULL DEFAULT NULL COMMENT '累计治愈',
  `heal_add` int(0) NULL DEFAULT NULL COMMENT '当日新增治愈',
  `dead` int(0) NULL DEFAULT NULL COMMENT '累计死亡',
  `dead_add` int(0) NULL DEFAULT NULL COMMENT '当日新增死亡',
  PRIMARY KEY (`ds`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

 

🍓项目结构


flaskProject文件夹中

  • app.py是flask项目主运行文件
  • sql_query.py是为flask项目封装的数据库操作文件
  • spider是项目所需的爬虫模块
  • static目录是项目静态资源
  • templates是项目的模板目录

🍓项目部分代码

🍅flask主体代码

# 主页路由
@app.route('/')
def index():
    # 判断是否执行爬虫
    res = sql_query.exSpider()
    # event表不空
    if len(res) != 0:
        dateTup = time.strptime(str(res[0][0]), "%Y-%m-%d %H:%M:%S")
        date = time.strftime("%Y-%m-%d", dateTup)
        # 当前时间
        nowTimeTup = time.localtime(time.time())
        nowDate = time.strftime("%Y-%m-%d", nowTimeTup)
        # 如果当前日期不等于event表中最后一条数据的日期
        if nowDate != date:
            # 执行爬虫
            main.run()
    # event表空,执行爬虫
    else:
        main.run()

    data = sql_query.getFinalData()
    dic_data = {
   "confirm": data[0],
                "heal": data[1],
                "dead": data[2],
                "now_local_confirm": data[3],
                "local_confirm_add": data[4],
                "local_no_infect_add": data[5]
                }
    # 将中间红色字体的统计数据也传到前端
    return render_template('index.html',**dic_data)

# 柱状图一数据获取
@app.route('/getBarData1',methods=["get","post"])
def get_Bar_Data1():
    res = []
    province = []
    datalist = []
    for tup in sql_query.getBarData1():
        province.append(tup[0])
        datalist.append(tup[1])
    res.append(province),res.append(datalist)
    return jsonify({
   "data": res})

# 柱状图二数据获取
@app.route('/getBarData2',methods=["get","post"])
def get_Bar_Data2():
    res = []
    for tup in sql_query.getBarData2():
        t = time.strptime(str(tup[0]), "%Y-%m-%d %H:%M:%S")
        event_time = str(t.tm_mon) + '-' + str(t.tm_mday) + " " + str(t.tm_hour) + ":" + str(t.tm_min)
        res.append(event_time + " " + tup[1])
    return jsonify({
   "data": res})

# 地图上方总数据获取
@app.route('/finalData',methods=["get","post"])
def get_final_Data():
    data = sql_query.getFinalData()
    return jsonify({
   "confirm": data[0], "heal": data[1], "dead": data[2],
                    "now_local_confirm": data[3],"local_confirm_add": data[4],
                    "local_no_infect_add": data[5]})

# 地图数据获取
@app.route("/getMapData",methods=["get","post"])
def get_Map_Data():
    # post请求参数在request.form中
    id = request.form.get("id")
    res = []
    for tup in sql_query.getMapData(id):
        res.append({
   "name": tup[0], "value": int(tup[1])})
    return jsonify({
   "data": res})

# 折线图一数据获取
@app.route("/getLineData1",methods=["get","post"])
def get_Line_Data1():
    res = []
    ds = []
    heal_add = []
    dead_add = []
    for tup in sql_query.getLineData1():
        # datetime.datetime要转换为str
        t = time.strptime(str(tup[0]), "%Y-%m-%d %H:%M:%S")
        ds.append(str(t.tm_mon) + '.' + str(t.tm_mday))
        heal_add.append(tup[1])
        dead_add.append(tup[2])
    res.append(ds),res.append(heal_add),res.append(dead_add)
    return jsonify({
   "data": res})

# 折线图二数据获取
@app.route("/getLineData2",methods=["get","post"])
def get_Line_Data2():
    res = []
    ds = []
    local_confirm_add = []
    local_no_infect_add = []
    for tup in sql_query.getLineData2():
        # datetime.datetime要转换为str
        t = time.strptime(str(tup[0]), "%Y-%m-%d %H:%M:%S")
        ds.append(str(t.tm_mon) + '.' + str(t.tm_mday))
        local_confirm_add.append(tup[1])
        local_no_infect_add.append(tup[2])
    res.append(ds),res.append(local_confirm_add),res.append(local_no_infect_add)
    return jsonify({
   "data": res})

# 饼图数据获取
@app.route("/getPieData",methods=["get","post"])
def get_Pie_Data():
    res = []
    for tup in sql_query.getPieData():
        res.append({
   "value":tup[1],"name":tup[0]})
    return jsonify({
   "data": res})

# 定时执行爬虫路由
@app.route("/setMessage",methods=["get","post"])
def set_Message():
    # 执行爬虫
    try:
        main.run()
        return jsonify({
   "success": 200})
    except:
        return jsonify({
   "success": 500})

 

🍅js更新数据代码

前端通过ajax向后端发送请求获取数据,然后渲染到echarts中!
同时设置了定时器,定时更新数据!

//向后台每两小时55分发送数据让其运行爬虫更新数据
function setMessage(){
   
    $.ajax({
   
        url: "/setMessage",
        type:"POST",
        success: function(data) {
   

        },
        error: function(xhr, type, errorThrown) {
   

        }
    })
}

setInterval(setMessage,175*60*1000);

//定时器,每三小时更新数据
setInterval(function(){
   
        get_final_data();
        getMapData(index);
        getBarData1();
        getBarData2();
        getLineData1();
        getLineData2();
        getPieData();
},3600*1000*3);

 

🍓项目启动!

建立好数据库表,更改你的数据配置之后,直接运行项目中的app.py文件即可!

🍓项目展示


🍓源码获取

项目已经上传到gitee,地址在这:
👉https://gitee.com/aniu-666/project
欢迎各位来star!

🍎结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉flask框架快速入门
👉java 小白到高手的蜕变

其他专栏请前往博主主页查看!


转载:https://blog.csdn.net/qq_57421630/article/details/127475275
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场