From 04e3ecba166f32c58366c945214a4ace8ef2dc54 Mon Sep 17 00:00:00 2001 From: lzh <52725224+Yourdaylight@users.noreply.github.com> Date: Sun, 1 Aug 2021 17:49:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=BA=E8=85=BE=E8=AE=AF=E7=96=AB=E6=83=85=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../项目源码/epidemic/app.py | 87 ++-- .../项目源码/epidemic/spider.py | 178 +++++-- .../项目源码/epidemic/static/css/main.css | 8 +- .../项目源码/epidemic/static/js/controller.js | 4 +- .../项目源码/epidemic/static/js/ec_c2.js | 2 +- .../项目源码/epidemic/static/js/ec_r1.js | 52 ++- .../项目源码/epidemic/templates/main.html | 8 +- .../项目源码/epidemic/test.py | 21 - .../项目源码/epidemic/translate.py | 434 ++++++++++++++++++ .../项目源码/epidemic/utils.py | 137 +++--- 10 files changed, 715 insertions(+), 216 deletions(-) delete mode 100644 python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/test.py create mode 100644 python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/translate.py diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/app.py b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/app.py index 5e84193..d59ca6d 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/app.py +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/app.py @@ -1,78 +1,81 @@ -from flask import Flask -from flask import render_template -from flask import jsonify import time + +from flask import Flask +from flask import jsonify +from flask import render_template + import utils + app = Flask(__name__) -#工具类,初始化参数为数据库名,数据库表名,数据库账号,数据库密码 -u=utils.utils("myspider","epidemic","root","123456") +# 工具类,初始化参数为数据库名,数据库表名,数据库账号,数据库密码 +u = utils.utils("myspider", "root", "123456") + + @app.route('/') def hello_world(): return render_template("main.html") + @app.route('/time') def get_time(): - time_str=time.strftime("%Y{}%m{}%d{}%X") - return time_str.format("年","月","日") + time_str = time.strftime("%Y{}%m{}%d{}%X") + return time_str.format("年", "月", "日") + @app.route('/c1') def get_c1_data(): - data=u.get_c1_data() + data = u.get_c1_data() print(data) - return jsonify({"dignose":data[0],"heal":data[1],"dead":data[2],"newly_add":data[3]}) + return jsonify({"dignose": data[0], "heal": data[1], "dead": data[2], "newly_add": data[3]}) @app.route('/c2') def get_c2_data(): - res=[] - data=u.get_c2_data() - for key,value in data.items(): - res.append({"name":key,"value":value}) - return jsonify({"data":res}) + res = [] + data = u.get_c2_data() + for key, value in data.items(): + res.append({"name": key, "value": value}) + return jsonify({"data": res}) + @app.route('/l1') def get_l1_data(): + data = u.get_l1_data() + day = data.date.tolist() + dignose = data.confirm.tolist() + heal = data.heal.tolist() + dead = data.dead.tolist() + return jsonify({"days": day, "dignose": dignose, "heal": heal, "dead": dead}) - data=u.get_l1_data() - day = [] - for d in data.index: - day.append(d.strftime("%m-%d")) - print(day) - dignose=data.确诊.tolist() - heal=data.治愈.tolist() - dead=data.死亡.tolist() - return jsonify({"days":day,"dignose":dignose,"heal":heal,"dead":dead}) @app.route('/l2') def get_l2_data(): data = u.get_l2_data() - day = [] - for d in data.index: - day.append(d.strftime("%m-%d")) - dignose=data.确诊.tolist() - heal=data.治愈.tolist() - dead=u.get_l1_data().新增死亡.tolist() - return jsonify({"days":day,"dignose":dignose,"heal":heal,"dead":dead}) + day = data.date.tolist() + dignose = data.confirm.tolist() + heal = data.heal.tolist() + dead = data.dead.tolist() + return jsonify({"days": day, "dignose": dignose, "heal": heal, "dead": dead}) + @app.route('/r1') def get_r1_data(): - data=u.get_r1_data() - keys=list(data.keys()) - values=list(data.values()) - print(keys,values) - return jsonify({"keys":keys,"values":values}) + data = u.get_r1_data() + keys = data.疫情地区.tolist() + values = data.确诊.tolist() + return jsonify({"keys": keys, "values": values}) + @app.route('/r2') def get_r2_data(): - res=[] - myutil=utils.utils("myspider","world_epidemic","root","123456") - data=myutil.get_r2_data() - for key, value in data.items(): + res = [] + data = u.get_r2_data() + for key, value in zip(data.name,data.确诊): res.append({"name": key, "value": value}) - #还需要添加中国的总数据 - china=int(u.get_c1_data()[0]) - res.append({"name":"China","value":china}) + # 还需要添加中国的总数据 + china = int(u.get_c1_data()[0]) + res.append({"name": "China", "value": china}) return jsonify({"data": res}) diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/spider.py b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/spider.py index 1e7ff7f..5fcb058 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/spider.py +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/spider.py @@ -1,57 +1,135 @@ -import requests +# -*- coding: utf-8 -*- +# @Time :2021/7/30 23:34 +# @Author :lzh +# @File : new_spider.py +# @Software: PyCharm +import datetime + import pandas as pd -import json +import requests from sqlalchemy import create_engine -url='https://voice.baidu.com/newpneumonia/get?target=trend&isCaseIn=0&stage=publish&callback=jsonp_1593074577909_83653' -r=requests.get(url).text +from translate import COUNTRIES_CH_EN_DICT -#标准化字符串为json格式 -r=r.replace("jsonp_1593074577909_83653(","") -r=r[0:-2] -r=json.loads(r) -names=[] -dates=[] -dignose=[] -heal=[] -dead=[] -add=[] -#遍历每个地点 -for place in r['data']: -# print(place['name']) - length=len(place['trend']['updateDate']) - place_name=(place['name'] for i in range(length)) - names.extend(place_name) - #获取日期数据 - dates.extend(place['trend']['updateDate']) - for trend in place['trend']['list']: - if(trend['name']=='确诊'): - dignose.extend(trend['data']) - if(trend['name']=='治愈'): - heal.extend(trend['data']) - if(trend['name']=='死亡'): - dead.extend(trend['data']) - if(trend['name']=='新增确诊'): - add.extend(trend['data']) +def traslate(word): + ''' + 将世界各国的中文名转化为英文 + ''' + return COUNTRIES_CH_EN_DICT.get(word, "未知地区") -#新增确诊数据如果存在缺失值,则将缺失值填充为0 -diff=len(names)-len(add) -if(diff!=0): - add=add+[0 for i in range(diff)] -print(len(names),len(dates),len(dignose),len(heal),len(dead),len(add)) -# 将数据保存至数据库中 -df=pd.DataFrame({ - "疫情地区":names, - "日期":dates, - "确诊":dignose, - "治愈":heal, - "死亡":dead, - "新增死亡":add -}) -df['日期']=['2020.'+i for i in df['日期']] -df['日期']=df['日期'].str.replace(".","-") -df['日期']=pd.to_datetime(df['日期']) -conn = create_engine('mysql://root:123456@localhost:3306/myspider?charset=utf8') -pd.io.sql.to_sql(df,'epidemic',con=conn,if_exists = 'replace',index=None) \ No newline at end of file +# %% +def save_data(df, table_name, if_exists="append", need_translate=False): + if need_translate: + df['name'] = df['疫情地区'].apply(traslate) + conn = create_engine('mysql://root:123456@localhost:3306/myspider?charset=utf8') + pd.io.sql.to_sql(df, table_name, con=conn, if_exists=if_exists, index=None) + + +def crawl_china_data(): + url = "https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=chinaDayList,chinaDayAddList,nowConfirmStatis,provinceCompare" + data = requests.get(url) + data = data.json().get("data", {}) + provinceCompare = data.get("provinceCompare") # 每个省份的总数据(每日更新) + chinaDayList = data.get("chinaDayList") # 最近一个月的全国疫情的总数据 + chinaDayAddList = data.get("chinaDayAddList") # 最近一个月的全国疫情的新增数据 + return provinceCompare, chinaDayList, chinaDayAddList + + +# %% +def crawl_countries_data(): + url = "https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=FAutoforeignList" + data = requests.get(url) + data = data.json().get("data") + foreignList = data.get("FAutoforeignList", []) + return foreignList + + +def parse_china_daily_data(day_list, day_add_list): + """ + 解析每日新增、每日累计数据 + :param api_rtn_data: + :return: + """ + day_df = pd.DataFrame(day_list) + day_df["date"] = pd.to_datetime(day_df["y"] + "." + day_df["date"]) + day_add_df = pd.DataFrame(day_add_list) + day_add_df["date"] = pd.to_datetime(day_add_df["y"] + "." + day_add_df["date"]) + save_data(day_df, "china_day", "append") + save_data(day_add_df, "china_day_add", "append") + + +def parse_countries_total_data(api_rtn_data): + """ + 解析每个省份的新增数据 + :param api_rtn_data: + :return: + """ + dates = [] + countries = [] + dignose = [] + heal = [] + dead = [] + add = [] + for country in api_rtn_data: + countries.append(country.get("name", "")) + month, day = country.get("date").split(".") + month = month if "0" not in month else month[-1] + date = datetime.date(int(country.get("y")), int(month), int(day)) + dates.append(date) + dignose.append(country.get("nowConfirm", 0)) + heal.append(country.get("heal", 0)) + dead.append(country.get("dead", 0)) + add.append(country.get("confirmAdd", 0)) + df = pd.DataFrame({ + "疫情地区": countries, + "日期": dates, + "确诊": dignose, + "治愈": heal, + "死亡": dead, + "新增死亡": add + }) + + save_data(df, "world_epidemic", "replace", True) + return df + + +def parse_provinces_total_data(api_rtn_data): + dates = [] + provinces = [] + dignose = [] + heal = [] + dead = [] + add = [] + for province, total_data in api_rtn_data.items(): + provinces.append(province) + date = datetime.datetime.now() + dates.append(date) + dignose.append(total_data.get("nowConfirm", 0)) + heal.append(total_data.get("heal", 0)) + dead.append(total_data.get("dead", 0)) + add.append(total_data.get("confirmAdd", 0)) + df = pd.DataFrame({ + "疫情地区": provinces, + "日期": dates, + "确诊": dignose, + "治愈": heal, + "死亡": dead, + "新增死亡": add + }) + save_data(df, 'china_total_epidemic') + return df + + +# %% +def main(): + provinceCompare, chinaDayList, chinaDayAddList = crawl_china_data() + parse_china_daily_data(chinaDayList, chinaDayAddList) + parse_provinces_total_data(provinceCompare) + parse_countries_total_data(crawl_countries_data()) + + +if __name__ == '__main__': + main() + print("爬取完成") diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/css/main.css b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/css/main.css index 43e41c8..3e7336f 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/css/main.css +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/css/main.css @@ -49,7 +49,7 @@ body{ } #l1{ position: absolute; - width: 30%; + width: 25%; height: 45%; top: 10%; left: 0%; @@ -57,7 +57,7 @@ body{ } #l2{ position: absolute; - width: 30%; + width: 25%; height: 45%; top: 55%; left: 0%; @@ -81,7 +81,7 @@ body{ } #r1{ position: absolute; - width: 30%; + width: 35%; height: 45%; top: 10%; right: 0%; @@ -89,7 +89,7 @@ body{ } #r2{ position: absolute; - width: 30%; + width: 35%; height: 45%; top: 55%; right: 0%; diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/controller.js b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/controller.js index 793af66..0ca8415 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/controller.js +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/controller.js @@ -81,7 +81,7 @@ function get_r1_data(){ url:"/r1", timeout:10000, success:function (data) { - ec_right1_option.xAxis.data=data.keys + ec_right1_option.xAxis[0].data=data.keys ec_right1_option.series[0].data=data.values ec_right1.setOption(ec_right1_option) }, @@ -114,4 +114,4 @@ get_l1_data() get_l2_data() get_r1_data() get_r2_data() -setInterval(gettime,1000) \ No newline at end of file +// setInterval(gettime,100000) \ No newline at end of file diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_c2.js b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_c2.js index f4d0ba2..fa7ccf7 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_c2.js +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_c2.js @@ -21,7 +21,7 @@ var ec_center_option = { color: ['#e0ffff', '#9D3030'] }, show:true, - splitList:[{start:1,end:9}, + splitList:[{start:0,end:9}, {start:10,end:99}, {start:100,end:999}, {start:1000,end:9999}, diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_r1.js b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_r1.js index 1a86d1a..d3bca08 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_r1.js +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/static/js/ec_r1.js @@ -1,24 +1,46 @@ -var ec_right1=echarts.init(document.getElementById("r1"),"dark") +var ec_right1 = echarts.init(document.getElementById("r1"), "dark") var ec_right1_option = { + + tooltip: { + trigger: 'axis', + axisPointer: { // 坐标轴指示器,坐标轴触发有效 + type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' + } + }, title: { - text: '非湖北地区确诊人数top5', + text: '全球地区确诊人数top5', left: "left" }, - xAxis: { - type: 'category', - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true }, - yAxis: { - type: 'value' - }, - series: [{ - data: [120, 200, 150, 80, 70, 110, 130], - type: 'bar', - showBackground: true, - backgroundStyle: { - color: 'rgba(220, 220, 220, 0.8)' + xAxis: [ + { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + axisTick: { + alignWithLabel: true + } } - }] + ], + yAxis: [ + { + type: 'value' + } + ], + series: [ + { + name: '确诊数量', + type: 'bar', + barWidth: '60%', + data: [10, 52, 200, 334, 390, 330, 220] + } + ] }; + + ec_right1.setOption(ec_right1_option) \ No newline at end of file diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/templates/main.html b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/templates/main.html index 8a5153d..98af32c 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/templates/main.html +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/templates/main.html @@ -23,12 +23,12 @@

累计确诊

累计治愈

累计死亡

-

新增死亡

+

现存确诊

-
我是中2
-
我是右1
-
我是右2
+
大屏中间第二幅图——中国疫情地图
+
大屏右侧第一幅图——全球确诊top5国家
+
大屏中间第二幅图——世界疫情地图
diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/test.py b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/test.py deleted file mode 100644 index 255fd17..0000000 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/test.py +++ /dev/null @@ -1,21 +0,0 @@ -from pyecharts import Bar -# from snapshot_selenium import snapshot -# from pyecharts.render import make_snapshot -columns = ['大大的三个字', '这里一共是十个字的吧', '这里一共是十个字的吧(这里是七个字)', '其他', '十全十美的十个字啊', 'python仪表盘', '快乐三个字', '可乐续保三个字', '骑缝三个字', - '里面好玩三个字', '信用卡三个字', '没空理我的', '订单问问三个字', '紫金学习三个字', '袋鼠妈妈三个字', '楼面价微信交流群', '密码三个字', '看见了来看看了解是是是', - '大门口流量数据', '烤面筋解决三个字', '到读到蓝莓味'] -# # 设置数据 -data1 = [841, 0, 136, 0, 3317, 784, 1, 19, 691, 131, 21, 6461, 123, 0, 692, 0, 0, 0, 0, 0, 0] -data2 = [13056, 16614, 701, 0, 5815, 4274, 256, 689, 13838, 21723, 0, 16073, 28297, 0, 279, 463, 25261, 60400, 0, 2493, - 16] -# # 设置柱状图的主标题与副标题 -bar = Bar("这里是大标题", "这里上介绍文字",width=1200,height=600) -# # 添加柱状图的数据及配置项 -def label_formatter(params): - return str(params.value)+"\t\t" -bar.add("外网", columns, data1, bar_category_gap='10%',label_formatter=label_formatter,xaxis_label_textsize=6,grid_bottom=500,label_text_size=8,is_label_show=True,xaxis_rotate=30) -bar.add("内网", columns, data2,bar_category_gap='10%',label_formatter=label_formatter,xaxis_label_textsize=6,grid_bottom=500,label_text_size=8,is_label_show=True, xaxis_rotate=30) -print(help(bar)) -# # 生成本地文件(默认为.html文件) -bar.render('tesss.jpg') -# make_snapshot(snapshot, bar.render(), "003_Options配置项_自定义样式_保存图片.png") \ No newline at end of file diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/translate.py b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/translate.py new file mode 100644 index 0000000..4ad1611 --- /dev/null +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/translate.py @@ -0,0 +1,434 @@ +COUNTRIES_EN_CH_DICT = { + "Somalia": "索马里", + "Liechtenstein": "列支敦士登", + "Morocco": "摩洛哥", + "W. Sahara": "西撒哈拉", + "Serbia": "塞尔维亚", + "Afghanistan": "阿富汗", + "Angola": "安哥拉", + "Albania": "阿尔巴尼亚", + "Andorra": "安道尔共和国", + "United Arab Emirates": "阿拉伯联合酋长国", + "Argentina": "阿根廷", + "Armenia": "亚美尼亚", + "Australia": "澳大利亚", + "Austria": "奥地利", + "Azerbaijan": "阿塞拜疆", + "Burundi": "布隆迪", + "Belgium": "比利时", + "Benin": "贝宁", + "Burkina Faso": "布基纳法索", + "Bangladesh": "孟加拉国", + "Bulgaria": "保加利亚", + "Bahrain": "巴林", + "Bahamas": "巴哈马", + "Bosnia and Herz.": "波斯尼亚和黑塞哥维那", + "Belarus": "白俄罗斯", + "Belize": "伯利兹", + "Bermuda": "百慕大", + "Bolivia": "玻利维亚", + "Brazil": "巴西", + "Barbados": "巴巴多斯", + "Brunei": "文莱", + "Bhutan": "不丹", + "Botswana": "博茨瓦纳", + "Central African Rep.": "中非", + "Canada": "加拿大", + "Switzerland": "瑞士", + "Chile": "智利", + "China": "中国", + "Côte dIvoire": "科特迪瓦", + "Cameroon": "喀麦隆", + "Dem. Rep. Congo": "刚果民主共和国", + "Congo": "刚果", + "Colombia": "哥伦比亚", + "Cape Verde": "佛得角", + "Costa Rica": "哥斯达黎加", + "Cuba": "古巴", + "N. Cyprus": "北塞浦路斯", + "Cyprus": "塞浦路斯", + "Czech Rep.": "捷克", + "Germany": "德国", + "Djibouti": "吉布提", + "Denmark": "丹麦", + "Dominican Rep.": "多米尼加", + "Algeria": "阿尔及利亚", + "Ecuador": "厄瓜多尔", + "Egypt": "埃及", + "Eritrea": "厄立特里亚", + "Spain": "西班牙", + "Estonia": "爱沙尼亚", + "Ethiopia": "埃塞俄比亚", + "Finland": "芬兰", + "Fiji": "斐济", + "France": "法国", + "Gabon": "加蓬", + "United Kingdom": "英国", + "Georgia": "格鲁吉亚", + "Ghana": "加纳", + "Guinea": "几内亚", + "Gambia": "冈比亚", + "Guinea-Bissau": "几内亚比绍", + "Eq. Guinea": "赤道几内亚", + "Greece": "希腊", + "Grenada": "格林纳达", + "Greenland": "格陵兰", + "Guatemala": "危地马拉", + "Guam": "关岛", + "Guyana": "圭亚那", + "Honduras": "洪都拉斯", + "Croatia": "克罗地亚", + "Haiti": "海地", + "Hungary": "匈牙利", + "Indonesia": "印度尼西亚", + "India": "印度", + "Br. Indian Ocean Ter.": "英属印度洋领土", + "Ireland": "爱尔兰", + "Iran": "伊朗", + "Iraq": "伊拉克", + "Iceland": "冰岛", + "Israel": "以色列", + "Italy": "意大利", + "Jamaica": "牙买加", + "Jordan": "约旦", + "Japan": "日本", + "Siachen Glacier": "锡亚琴冰川", + "Kazakhstan": "哈萨克斯坦", + "Kenya": "肯尼亚", + "Kyrgyzstan": "吉尔吉斯坦", + "Cambodia": "柬埔寨", + "Korea": "韩国", + "Kuwait": "科威特", + "Lao PDR": "老挝", + "Lebanon": "黎巴嫩", + "Liberia": "利比里亚", + "Libya": "利比亚", + "Sri Lanka": "斯里兰卡", + "Lesotho": "莱索托", + "Lithuania": "立陶宛", + "Luxembourg": "卢森堡", + "Latvia": "拉脱维亚", + "Moldova": "摩尔多瓦", + "Madagascar": "马达加斯加", + "Mexico": "墨西哥", + "Macedonia": "马其顿", + "Mali": "马里", + "Malta": "马耳他", + "Myanmar": "缅甸", + "Montenegro": "黑山", + "Mongolia": "蒙古", + "Mozambique": "莫桑比克", + "Mauritania": "毛里塔尼亚", + "Mauritius": "毛里求斯", + "Malawi": "马拉维", + "Malaysia": "马来西亚", + "Namibia": "纳米比亚", + "New Caledonia": "新喀里多尼亚", + "Niger": "尼日尔", + "Nigeria": "尼日利亚", + "Nicaragua": "尼加拉瓜", + "Netherlands": "荷兰", + "Norway": "挪威", + "Nepal": "尼泊尔", + "New Zealand": "新西兰", + "Oman": "阿曼", + "Pakistan": "巴基斯坦", + "Panama": "巴拿马", + "Peru": "秘鲁", + "Philippines": "菲律宾", + "Papua New Guinea": "巴布亚新几内亚", + "Poland": "波兰", + "Puerto Rico": "波多黎各", + "Dem. Rep. Korea": "朝鲜", + "Portugal": "葡萄牙", + "Paraguay": "巴拉圭", + "Palestine": "巴勒斯坦", + "Qatar": "卡塔尔", + "Romania": "罗马尼亚", + "Russia": "俄罗斯", + "Rwanda": "卢旺达", + "Saudi Arabia": "沙特阿拉伯", + "Sudan": "苏丹", + "S. Sudan": "南苏丹", + "Senegal": "塞内加尔", + "Singapore": "新加坡", + "Solomon Is.": "所罗门群岛", + "Sierra Leone": "塞拉利昂", + "El Salvador": "萨尔瓦多", + "Suriname": "苏里南", + "Slovakia": "斯洛伐克", + "Slovenia": "斯洛文尼亚", + "Sweden": "瑞典", + "Swaziland": "斯威士兰", + "Seychelles": "塞舌尔", + "Syria": "叙利亚", + "Chad": "乍得", + "Togo": "多哥", + "Thailand": "泰国", + "Tajikistan": "塔吉克斯坦", + "Turkmenistan": "土库曼斯坦", + "Timor-Leste": "东帝汶", + "Tonga": "汤加", + "Trinidad and Tobago": "特立尼达和多巴哥", + "Tunisia": "突尼斯", + "Turkey": "土耳其", + "Tanzania": "坦桑尼亚", + "Uganda": "乌干达", + "Ukraine": "乌克兰", + "Uruguay": "乌拉圭", + "United States": "美国", + "Uzbekistan": "乌兹别克斯坦", + "Venezuela": "委内瑞拉", + "Vietnam": "越南", + "Vanuatu": "瓦努阿图", + "Yemen": "也门", + "South Africa": "南非", + "Zambia": "赞比亚", + "Zimbabwe": "津巴布韦", + "Aland": "奥兰群岛", + "American Samoa": "美属萨摩亚", + "Fr. S. Antarctic Lands": "南极洲", + "Antigua and Barb.": "安提瓜和巴布达", + "Comoros": "科摩罗", + "Curaçao": "库拉索岛", + "Cayman Is.": "开曼群岛", + "Dominica": "多米尼加", + "Falkland Is.": "马尔维纳斯群岛(福克兰)", + "Faeroe Is.": "法罗群岛", + "Micronesia": "密克罗尼西亚", + "Heard I. and McDonald Is.": "赫德岛和麦克唐纳群岛", + "Isle of Man": "曼岛", + "Jersey": "泽西岛", + "Kiribati": "基里巴斯", + "Saint Lucia": "圣卢西亚", + "N. Mariana Is.": "北马里亚纳群岛", + "Montserrat": "蒙特塞拉特", + "Niue": "纽埃", + "Palau": "帕劳", + "Fr. Polynesia": "法属波利尼西亚", + "S. Geo. and S. Sandw. Is.": "南乔治亚岛和南桑威奇群岛", + "Saint Helena": "圣赫勒拿", + "St. Pierre and Miquelon": "圣皮埃尔和密克隆群岛", + "São Tomé and Principe": "圣多美和普林西比", + "Turks and Caicos Is.": "特克斯和凯科斯群岛", + "St. Vin. and Gren.": "圣文森特和格林纳丁斯", + "U.S. Virgin Is.": "美属维尔京群岛", + "Samoa": "萨摩亚" +} +# 中文-英文字典 +COUNTRIES_CH_EN_DICT = { + "索马里": "Somalia", + "列支敦士登": "Liechtenstein", + "摩洛哥": "Morocco", + "西撒哈拉": "W. Sahara", + "塞尔维亚": "Serbia", + "阿富汗": "Afghanistan", + "安哥拉": "Angola", + "阿尔巴尼亚": "Albania", + "安道尔共和国": "Andorra", + "阿拉伯联合酋长国": "United Arab Emirates", + "阿根廷": "Argentina", + "亚美尼亚": "Armenia", + "澳大利亚": "Australia", + "奥地利": "Austria", + "阿塞拜疆": "Azerbaijan", + "布隆迪": "Burundi", + "比利时": "Belgium", + "贝宁": "Benin", + "布基纳法索": "Burkina Faso", + "孟加拉国": "Bangladesh", + "保加利亚": "Bulgaria", + "巴林": "Bahrain", + "巴哈马": "Bahamas", + "波斯尼亚和黑塞哥维那": "Bosnia and Herz.", + "白俄罗斯": "Belarus", + "伯利兹": "Belize", + "百慕大": "Bermuda", + "玻利维亚": "Bolivia", + "巴西": "Brazil", + "巴巴多斯": "Barbados", + "文莱": "Brunei", + "不丹": "Bhutan", + "博茨瓦纳": "Botswana", + "中非": "Central African Rep.", + "加拿大": "Canada", + "瑞士": "Switzerland", + "智利": "Chile", + "中国": "China", + "科特迪瓦": "Côte dIvoire", + "喀麦隆": "Cameroon", + "刚果民主共和国": "Dem. Rep. Congo", + "刚果": "Congo", + "哥伦比亚": "Colombia", + "佛得角": "Cape Verde", + "哥斯达黎加": "Costa Rica", + "古巴": "Cuba", + "北塞浦路斯": "N. Cyprus", + "塞浦路斯": "Cyprus", + "捷克": "Czech Rep.", + "德国": "Germany", + "吉布提": "Djibouti", + "丹麦": "Denmark", + "多米尼加": "Dominica", + "阿尔及利亚": "Algeria", + "厄瓜多尔": "Ecuador", + "埃及": "Egypt", + "厄立特里亚": "Eritrea", + "西班牙": "Spain", + "爱沙尼亚": "Estonia", + "埃塞俄比亚": "Ethiopia", + "芬兰": "Finland", + "斐济": "Fiji", + "法国": "France", + "加蓬": "Gabon", + "英国": "United Kingdom", + "格鲁吉亚": "Georgia", + "加纳": "Ghana", + "几内亚": "Guinea", + "冈比亚": "Gambia", + "几内亚比绍": "Guinea-Bissau", + "赤道几内亚": "Eq. Guinea", + "希腊": "Greece", + "格林纳达": "Grenada", + "格陵兰": "Greenland", + "危地马拉": "Guatemala", + "关岛": "Guam", + "圭亚那": "Guyana", + "洪都拉斯": "Honduras", + "克罗地亚": "Croatia", + "海地": "Haiti", + "匈牙利": "Hungary", + "印度尼西亚": "Indonesia", + "印度": "India", + "英属印度洋领土": "Br. Indian Ocean Ter.", + "爱尔兰": "Ireland", + "伊朗": "Iran", + "伊拉克": "Iraq", + "冰岛": "Iceland", + "以色列": "Israel", + "意大利": "Italy", + "牙买加": "Jamaica", + "约旦": "Jordan", + "日本": "Japan", + "锡亚琴冰川": "Siachen Glacier", + "哈萨克斯坦": "Kazakhstan", + "肯尼亚": "Kenya", + "吉尔吉斯坦": "Kyrgyzstan", + "柬埔寨": "Cambodia", + "韩国": "Korea", + "科威特": "Kuwait", + "老挝": "Lao PDR", + "黎巴嫩": "Lebanon", + "利比里亚": "Liberia", + "利比亚": "Libya", + "斯里兰卡": "Sri Lanka", + "莱索托": "Lesotho", + "立陶宛": "Lithuania", + "卢森堡": "Luxembourg", + "拉脱维亚": "Latvia", + "摩尔多瓦": "Moldova", + "马达加斯加": "Madagascar", + "墨西哥": "Mexico", + "马其顿": "Macedonia", + "马里": "Mali", + "马耳他": "Malta", + "缅甸": "Myanmar", + "黑山": "Montenegro", + "蒙古": "Mongolia", + "莫桑比克": "Mozambique", + "毛里塔尼亚": "Mauritania", + "毛里求斯": "Mauritius", + "马拉维": "Malawi", + "马来西亚": "Malaysia", + "纳米比亚": "Namibia", + "新喀里多尼亚": "New Caledonia", + "尼日尔": "Niger", + "尼日利亚": "Nigeria", + "尼加拉瓜": "Nicaragua", + "荷兰": "Netherlands", + "挪威": "Norway", + "尼泊尔": "Nepal", + "新西兰": "New Zealand", + "阿曼": "Oman", + "巴基斯坦": "Pakistan", + "巴拿马": "Panama", + "秘鲁": "Peru", + "菲律宾": "Philippines", + "巴布亚新几内亚": "Papua New Guinea", + "波兰": "Poland", + "波多黎各": "Puerto Rico", + "朝鲜": "Dem. Rep. Korea", + "葡萄牙": "Portugal", + "巴拉圭": "Paraguay", + "巴勒斯坦": "Palestine", + "卡塔尔": "Qatar", + "罗马尼亚": "Romania", + "俄罗斯": "Russia", + "卢旺达": "Rwanda", + "沙特阿拉伯": "Saudi Arabia", + "苏丹": "Sudan", + "南苏丹": "S. Sudan", + "塞内加尔": "Senegal", + "新加坡": "Singapore", + "所罗门群岛": "Solomon Is.", + "塞拉利昂": "Sierra Leone", + "萨尔瓦多": "El Salvador", + "苏里南": "Suriname", + "斯洛伐克": "Slovakia", + "斯洛文尼亚": "Slovenia", + "瑞典": "Sweden", + "斯威士兰": "Swaziland", + "塞舌尔": "Seychelles", + "叙利亚": "Syria", + "乍得": "Chad", + "多哥": "Togo", + "泰国": "Thailand", + "塔吉克斯坦": "Tajikistan", + "土库曼斯坦": "Turkmenistan", + "东帝汶": "Timor-Leste", + "汤加": "Tonga", + "特立尼达和多巴哥": "Trinidad and Tobago", + "突尼斯": "Tunisia", + "土耳其": "Turkey", + "坦桑尼亚": "Tanzania", + "乌干达": "Uganda", + "乌克兰": "Ukraine", + "乌拉圭": "Uruguay", + "美国": "United States", + "乌兹别克斯坦": "Uzbekistan", + "委内瑞拉": "Venezuela", + "越南": "Vietnam", + "瓦努阿图": "Vanuatu", + "也门": "Yemen", + "南非": "South Africa", + "赞比亚": "Zambia", + "津巴布韦": "Zimbabwe", + "奥兰群岛": "Aland", + "美属萨摩亚": "American Samoa", + "南极洲": "Fr. S. Antarctic Lands", + "安提瓜和巴布达": "Antigua and Barb.", + "科摩罗": "Comoros", + "库拉索岛": "Curaçao", + "开曼群岛": "Cayman Is.", + "马尔维纳斯群岛(福克兰)": "Falkland Is.", + "法罗群岛": "Faeroe Is.", + "密克罗尼西亚": "Micronesia", + "赫德岛和麦克唐纳群岛": "Heard I. and McDonald Is.", + "曼岛": "Isle of Man", + "泽西岛": "Jersey", + "基里巴斯": "Kiribati", + "圣卢西亚": "Saint Lucia", + "北马里亚纳群岛": "N. Mariana Is.", + "蒙特塞拉特": "Montserrat", + "纽埃": "Niue", + "帕劳": "Palau", + "法属波利尼西亚": "Fr. Polynesia", + "南乔治亚岛和南桑威奇群岛": "S. Geo. and S. Sandw. Is.", + "圣赫勒拿": "Saint Helena", + "圣皮埃尔和密克隆群岛": "St. Pierre and Miquelon", + "圣多美和普林西比": "São Tomé and Principe", + "特克斯和凯科斯群岛": "Turks and Caicos Is.", + "圣文森特和格林纳丁斯": "St. Vin. and Gren.", + "美属维尔京群岛": "U.S. Virgin Is.", + "萨摩亚": "Samoa" +} diff --git a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/utils.py b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/utils.py index 822bc72..afc8824 100644 --- a/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/utils.py +++ b/python+flask实现全国+全球疫情数据可视化/项目源码/epidemic/utils.py @@ -1,70 +1,76 @@ +import datetime +import traceback + +import pandas as pd import pymysql from sqlalchemy import create_engine -import pandas as pd -import datetime + + class utils: - def __init__(self,db_name,table_name,user,password): - self.db_name=db_name - self.table_name=table_name - self.user=user - self.password=password - self.data = self.querry() + def __init__(self, db_name, user, password): + self.db_name = db_name + self.user = user + self.password = password + self.data = self.query("epidemic") + def get_conn(self): ''' :return:连接 ''' - #创建连接 - conn=pymysql.connect(host="127.0.0.1",port=3306,user=self.user,password=self.password, - db=self.db_name,charset="utf8") - cursor=conn.cursor() - return conn,cursor + # 创建连接 + conn = pymysql.connect(host="127.0.0.1", port=3306, user=self.user, password=self.password, + db=self.db_name, charset="utf8") + cursor = conn.cursor() + return conn, cursor - def close_conn(self,conn,cursor): + def close_conn(self, conn, cursor): cursor.close() conn.close() - def querry(self): - #使用pandas从数据库中读取疫情数据 - conn = create_engine('mysql://{}:{}@localhost:3306/{}?charset=utf8'.format(self.user,self.password,self.db_name)) - sql="SELECT * FROM {}".format(self.table_name) - epidemic = pd.read_sql(sql, con=conn) - return epidemic + def query(self, table_name, use_sql=None): + """ + :param sql: + :return:epidemic: DataFrame + """ + # 使用pandas从数据库中读取疫情数据 + try: + conn = create_engine('mysql://{}:{}@localhost:3306/{}?charset=utf8'.format(self.user, self.password, self.db_name)) + sql = use_sql if use_sql else "select * from {}".format(table_name) + epidemic = pd.read_sql(sql, con=conn) + return epidemic + except Exception as e: + traceback.print_exc(e) + return None def get_c1_data(self): ''' 获取c1的四个数据:累计确诊、累计治愈、累计死亡、新增死亡 :return: ''' - df=self.data - #获取最新数据 - # 由于接口数据只能拿到前一天,因此我们的日期数据应该-1天 - t = datetime.datetime.now() + datetime.timedelta(days=-1) - t= t.strftime('%Y-%m-%d') - today = df[df.日期 == t] - dignose=str(today.确诊.sum()) - heal=str(today.治愈.sum()) - dead=str(today.死亡.sum()) - add=str(today.新增死亡.sum()) + sql = "select date, confirm, nowConfirm,heal,dead from china_day order by date desc limit 1" + df = self.query("china_day", sql) + confirm = int(df["confirm"][0]) + heal = int(df["heal"][0]) + dead = int(df["dead"][0]) + now_confirm = int(df["nowConfirm"][0]) - return [dignose,heal,dead,add] + return [confirm, heal, dead, now_confirm] def get_c2_data(self): ''' 获取中国各省的疫情数据 :return: ''' - #将地区-确诊人数以键值对的形式保存 - dict={} + # 将地区-确诊人数以键值对的形式保存 + dict = {} # 获取最新数据 - # 由于接口数据只能拿到前一天,因此我们的日期数据应该-1天 - df=self.data - t = datetime.datetime.now() + datetime.timedelta(days=-1) - t = t.strftime('%Y-%m-%d') - today = df[df.日期 == t] - for p,v in zip(today.疫情地区,today.确诊): - dict[p]=v + # 从数据库中获取最近一次更新的数据 + sql = "select distinct 疫情地区,日期,确诊 from china_total_epidemic order by 日期 desc limit 34" + df = self.query("china_total_epidemic", sql) + for p, v in zip(df.疫情地区, df.确诊): + dict[p] = v return dict def get_l1_data(self): @@ -72,61 +78,38 @@ class utils: 获取疫情期间每日累计数据 :return: ''' - df=self.data - days=df.groupby("日期").sum() - return days + sql = "select date, confirm, heal,dead from china_day order by date desc" + df = self.query("", sql) + return df def get_l2_data(self): ''' 获取疫情期间每日新增数据 :return: ''' - df=self.data - days=df.groupby("日期").sum().diff().dropna() - return days + sql = "select date, confirm,heal,dead from china_day_add order by date desc" + df = self.query("",sql) + return df def get_r1_data(self): ''' 获取除湖北地区确诊人数最多的省份 :return: ''' - dict={} - df=self.data - t = datetime.datetime.now() + datetime.timedelta(days=-1) - t = t.strftime('%Y-%m-%d') - today = df[df.日期 == t] - #按确诊人数排序 - today=today.sort_values(by='确诊',ascending=False)[:6] - for key,value in zip(today.疫情地区,today.确诊): - if key=='湖北': - continue - dict[key]=value - - return dict + sql = "select 疫情地区,确诊 from world_epidemic order by 日期 desc limit 5" + df = self.query("",sql) + return df def get_r2_data(self): ''' 获取世界各国的疫情数据 :return: ''' - #将地区-确诊人数以键值对的形式保存 - dict={} - - # 获取最新数据 - # 由于接口数据只能拿到前一天,因此我们的日期数据应该-1天 - df=self.data - t = datetime.datetime.now() + datetime.timedelta(days=-1) - t = t.strftime('%Y-%m-%d') - today = df[df.日期 == t] - for p,v in zip(today.name,today.确诊): - dict[p]=v - return dict + df = self.query("world_epidemic") + return df[["name","疫情地区","确诊"]] +if __name__ == "__main__": + u = utils("myspider", "root", "123456") - - -if __name__=="__main__": - u=utils("myspider","world_epidemic","root","123456") - print(list(u.get_r1_data().values())) - + u.get_c1_data()