题目一:疫情数据分析
编写程序(用Java或Python或javascript)获取实时疫情数据,并进行统计分析,显示各种统计图。
获取大数据,进行统计分析是大数据技术研究的基础。
巩固之前学习的Python、Django。
学习掌握数据可视化工具:echarts。
学习掌握爬虫流程与方法。
对收集的数据可视化。
提升遇到问题、解决问题的能力。
操作系统:Windows 10 (x64)
处理器:Intel® Core™ i5-7200U
内存:4.00GB
IDE:JetBrains PyCharm Professional Edition with Anaconda plugin 2019.2.6 x64
数据库:MySQL 5.55
Python版本:Python 3.7
Django版本:Django 1.11.11
Django是一个开放源代码的Web应用框架,由Python写成。采用了MTV的框架模式,即模型M,视图V和模版T。
Django 框架的核心组件有:
用于创建模型的对象关系映射;
为最终用户设计较好的管理界面;
URL 设计;
设计者友好的模板语言;
缓存系统。
Django 的 MTV 分别是指:
M模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
T模板 (Template):负责如何把页面(html)展示给用户。
V视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。
设计、实现:html页面布局(即Template)、Model存储数据、View业务逻辑。
在实现过程中多次运行,发现bug及时修改。
Utools上有个“内网穿透”的插件,可以把运行的Web通过外网查看,方便老师看到实现的效果。
创建Django项目
创建子应用
python manager.py startapp info
设置setting文件
#ALLOWED_HOSTS是一个字符串列表,代表了这个Django网站可以服务的主机名或域名。这是为了阻止HTTP Host头攻击而采用的一种安全措施
ALLOWED_HOSTS = ['covdjango.utools.club','127.0.0.1']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'info.apps.InfoConfig', #添加子应用
]
#数据库设置,默认数据库改为MySQL数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库用户密码
'NAME': 'Cov_django' # 数据库名字
}
}
LANGUAGE_CODE = 'zh-Hans'#语言
TIME_ZONE = 'Asia/Shanghai'#时区
#静态文件 在static添加的任何静态文件都可以使用网址/static/文件在static中的路径来访问了
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
设置Cov_django访问地址urls.py文件
from django.contrib import admin
from django.conf.urls import url,include
urlpatterns = [
url(r'^admin/', admin.site.urls),#在设置管理员的情况下访问地址后以为admin/则进入到管理员界面
url(r'^',include('info.urls',namespace='info')),#根据正则表达式顺序匹配,匹配不成功就匹配下一个,直到匹配成功为止,全没匹配成功返回404
#第二个匹配成功后会进入到info下的urls继续进行二级匹配
]
设置子应用下urls文件
from django.conf.urls import url
from info.views import index
app_name = 'info'
urlpatterns = [
url(r'^$',index,name = 'index'),
url(r'^index/$',index,name = 'index'),#连个都返回到views下index实现业务逻辑
]
本实验采用的是腾讯的数据:
国外各国实时疫情数据
地址: 新冠肺炎疫情最新动态,实时更新 - 腾讯
F12打开开发者模式可看到以下内容:
在请求网页爬取的时候,输出的text信息中会出现抱歉,无法访问等字眼,这就是禁止爬取,需要通过反爬机制去解决这个问题。headers是解决requests请求反爬的方法之一,相当于我们进去这个网页的服务器本身,假装自己本身在爬取数据。对反爬虫网页,可以设置一些headers信息,模拟成浏览器取访问网站 。
在info子应用下创建一个名为‘CrawlingDataUtils.py’爬虫工具文件,里面封装了爬虫方法
import requests #用于请求页面,得到相应内容
import json #将实现数据字到json的互相转换
import jsonpath #当遇到层级比较深的字典时,要想取值使用jsonpath取值比较方便,可以一下取到。
#获取每日全球数据信息
def get_globalStatis_data():
url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign' #请求地址
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
} #请求头,作用:伪装成浏览器反爬虫
#这个网址请求方式为get
r = requests.get(url, headers)
res = json.loads(r.text) # 将网页中的json字符串 转成 字典
data_all = json.loads(res['data']) #根据数据格式,进一步拆分数据,得到想要的data数据
lastUpdateTime = data_all['globalStatis']['lastUpdateTime'] # Time格式:YYYY-MM-DD HH:mm:ss
nowConfirm = data_all['globalStatis']['nowConfirm']
confirm = data_all['globalStatis']["confirm"]
heal = data_all['globalStatis']["heal"]
dead = data_all['globalStatis']["dead"]
nowConfirmAdd = data_all['globalStatis']['nowConfirmAdd']
confirmAdd = data_all['globalStatis']['confirmAdd']
healAdd = data_all['globalStatis']['healAdd']
deadAdd = data_all['globalStatis']['deadAdd']
#将上述数据组合成字典,方便返回与获取
globalStatis = {"lastUpdateTime": lastUpdateTime, "nowConfirm": nowConfirm, "confirm": confirm, "heal": heal,
"dead": dead,
"nowConfirmAdd": nowConfirmAdd, "confirmAdd": confirmAdd, "healAdd": healAdd,
"deadAdd": deadAdd}
return globalStatis
#获取外国数据
def get_foreign_data():
# 1.目标网站
url = 'https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist'
# 2.请求资源 Request Method: POST
resp = requests.post(url)
# print(resp.text)
# 3.提取数据
# 类型转换 json-->dict
data = json.loads(resp.text)
# print(type(data))
# for i in range(0,len(data['data'])) :
# print(data['data'][i]['name'])
# data是我们的内容,$表示根节点下,而$..name表示根节点下的任意层级name键值的部分
name = jsonpath.jsonpath(data, "$..name")#JsonPath是一种简单的方法来提取给定JSON文档的部分内容
confirm = jsonpath.jsonpath(data, "$..confirm") #返回是各个国家的confirm组成的列表
confirmAdd = jsonpath.jsonpath(data, "$..confirmAdd")
confirmCompare = jsonpath.jsonpath(data, "$..confirmCompare")
date = jsonpath.jsonpath(data, "$..date")
dead = jsonpath.jsonpath(data, "$..dead")
deadCompare = jsonpath.jsonpath(data, "$..deadCompare")
heal = jsonpath.jsonpath(data, "$..heal")
healCompare = jsonpath.jsonpath(data, "$..healCompare")
nowConfirm = jsonpath.jsonpath(data, "$..nowConfirm")
nowConfirmCompare = jsonpath.jsonpath(data, "$..nowConfirmCompare")
#zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
#返回的是[(一个国家各项数据组成的元组),(一个国家各项数据组成的元组)...]
data_list = list(zip(name,confirm,confirmAdd,confirmCompare,date,dead,deadCompare,heal,healCompare,nowConfirm,nowConfirmCompare))
#返回各项数据,其中data_list是方便向数据库中添加一条数据,其他的方便echarts使用(echarts坐标为列表形式的数据)
return [name,confirm,confirmAdd,confirmCompare,date,dead,deadCompare,heal,healCompare,nowConfirm,nowConfirmCompare,data_list]
#获取美国历史确诊数据
def get_USA_history_confirm_data():
url = 'https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=FAutoCountryMerge'
resp = requests.post(url)
dic = json.loads(resp.text)
nation_data = dic['data']['FAutoCountryMerge']
usaData = nation_data['美国']['list']
# 由字典组成的列表 [{'date': '01.28', 'confirm': 5},{'date': '01.29', 'confirm': 5},...]
return usaData
#获取全球每日数据
def get_GlobalDailyList():
url = 'https://api.inews.qq.com/newsqa/v1/automation/modules/list?modules=FAutoGlobalStatis,FAutoContinentStatis,FAutoGlobalDailyList,FAutoCountryConfirmAdd'
resp = requests.post(url)
dic = json.loads(resp.text)
ls = dic['data']['FAutoGlobalDailyList'] #list 昨天以前全球疫情数据
today = dic['data']['FAutoGlobalStatis'] #字典 今天全球疫情数据
#[{'date': '01.28',
# 'all': {'confirm': 57,
# 'dead': 0,
# 'heal': 3,
# 'newAddConfirm': 0,
# 'deadRate': '0.00',
# 'healRate': '5.26'}},
# {'date': '01.29',
# 'all': {'confirm': 74,
# 'dead': 0,
# 'heal': 3,
# 'newAddConfirm': 13,
# 'deadRate': '0.00',
# 'healRate': '4.05'}},......]
return {'ls':ls,'today':today}
#整合历史数据 :日期date/美国确诊usaconfirm/全球确诊、全球死亡、全球治愈、全球新增,方便插入数据库中
def get_all_data():
usaData = get_USA_history_confirm_data()
all_date = jsonpath.jsonpath(usaData, "$..date")
USA_history_confirm = jsonpath.jsonpath(usaData, "$..confirm")
#全球历史疫情数据
ls = get_GlobalDailyList()['ls']
today = get_GlobalDailyList()['today']
before_confirm = jsonpath.jsonpath(ls,"$..confirm")
before_dead = jsonpath.jsonpath(ls,"$..dead")
before_heal = jsonpath.jsonpath(ls,"$..heal")
before_newAddConfirm = jsonpath.jsonpath(ls,"$..newAddConfirm") #新增确诊
today_confirm = today['confirm']
today_dead = today['dead']
today_heal = today['heal']
today_confirmAdd = today['confirmAdd']
before_confirm.append(today_confirm)
# print(all_confirm):None append这个操作是没有返回值的(即返回一个None),b.append(a) append只更新b本身,正确的写法应该分开写:
before_dead.append(today_dead)
#all_dead = before_dead #before_dead 添加完today的数据,就为全的数据了 ==all_dead
before_heal.append(today_heal)
before_newAddConfirm.append(today_confirmAdd)
datalist = list(zip(all_date,USA_history_confirm,before_confirm,before_dead,before_heal,before_newAddConfirm))
return datalist
#https://voice.baidu.com/newpneumonia/get?target=trend&isCaseIn=1&stage=publish&callback=jsonp_1594382062559_46273
#https://voice.baidu.com/act/newpneumonia/newpneumonia#tab4 有国外的历史数据
Models中的class对应数据库中的表,属性对应字段。
models.py
中定义模型类,继承自models.Model
#定义模型类
from django.db import models
# Create your models here.
class foreign_data(models.Model):
date = models.DateField(verbose_name='更新时间')
name = models.CharField(max_length=20,verbose_name='国家')
confirm = models.IntegerField(verbose_name='确认总数')
confirmAdd = models.IntegerField(verbose_name='新增确诊人数')
heal = models.IntegerField(verbose_name='治愈人数')
dead = models.IntegerField(verbose_name='死亡人数')
nowConfirm = models.IntegerField(verbose_name='现存确诊')
class Meta:
#改表名
db_table = 'foreign_data'
#修改后台admin对的显示信息的配置
verbose_name_plural = '国外疫情数据(每个国家不同日期的数据)'
def __str__(self):
#后台显示
return self.name +':' + str(self.date)
class globalStatic(models.Model):
lastUpdateTime = models.DateTimeField(verbose_name='更新时间')
nowConfirm = models.IntegerField(verbose_name='现存确诊')
confirm = models.IntegerField(verbose_name='确认总数')
heal = models.IntegerField( verbose_name='治愈人数')
dead = models.IntegerField(verbose_name='死亡人数')
nowConfirmAdd = models.IntegerField(verbose_name='新增现存确诊人数')
confirmAdd = models.IntegerField(verbose_name='新增确诊人数')
healAdd = models.IntegerField(verbose_name='新增治愈人数')
deadAdd = models.IntegerField(verbose_name='新增死亡人数')
class Meta:
# 改表名
db_table = 'globalStatic'
# 修改后台admin对的显示信息的配置
verbose_name_plural = '全球疫情总数据'
def __str__(self):
return '更新时间'+str(self.lastUpdateTime)
class USA_history_confirm_data(models.Model):
date = models.DateField(verbose_name='日期')
confirm = models.IntegerField(verbose_name='确认数')
class Meta:
# 改表名
db_table = 'USA_history_confirm_data'
# 修改后台admin对的显示信息的配置
verbose_name_plural = '美国历史疫情数据'
def __str__(self):
return '日期:'+str(self.date)
#全球疫情实体类
class usa_global_all_data(models.Model):
date = models.DateField(verbose_name='日期')
usaconfirm = models.IntegerField(verbose_name='美国确诊')
confirm = models.IntegerField(verbose_name='全球确诊')
dead = models.IntegerField(verbose_name='全球死亡')
heal = models.IntegerField(verbose_name='全球治愈')
confirmAdd = models.IntegerField(verbose_name='全球新增')
class Meta:
# 改表名
db_table = 'usa_global_all_data'
# 修改后台admin对的显示信息的配置
verbose_name_plural = '美国和全球历史疫情数据'
def __str__(self):
return '日期:'+str(self.date)
迁移由两步完成 :
生成迁移文件:根据模型类生成创建表的语句
python manage.py makemigrations
执行迁移:根据第一步生成的语句在数据库中创建表
python manage.py migrate
在info子应用下创建一个名为‘dbUtils.py’数据库操作工具文件,里面封装了数据库操作方法
from info.models import globalStatic,foreign_data,USA_history_confirm_data,usa_global_all_data
from info.CrawlingDataUtils import get_globalStatis_data,get_foreign_data,get_USA_history_confirm_data,get_all_data
import time
# 数据库中添加foreign_data
def insert_foreign_data():
foreignData = get_foreign_data()
ls = foreignData[11] #数据下标为11的数据是每个(国家数据的元组)组成的列表
print(f"{time.asctime()}开始插入各国数据")
for i in range(0,len(ls)):
ds = "2020." + ls[i][4]
tup = time.strptime(ds, "%Y.%m.%d")
date = time.strftime("%Y-%m-%d", tup)
foreign_data.objects.get_or_create(
#get_or_create若数据库中没有这条数据就插入,若已存在就不插入,避免数据是重复
date=date,
name=ls[i][0],
confirm=ls[i][1],
confirmAdd=ls[i][2],
heal=ls[i][7],
dead=ls[i][5],
nowConfirm=ls[i][9],
)
print(f"{time.asctime()}插入数据完毕")
def insert_globalStatic():
dict = get_globalStatis_data() # 全球数据字典
print(f"{time.asctime()}开始插入全球数据")
globalStatic.objects.get_or_create(
lastUpdateTime=dict['lastUpdateTime'],
nowConfirm=dict['nowConfirm'],
confirm=dict['confirm'],
heal=dict['heal'],
dead=dict['dead'],
nowConfirmAdd=dict['nowConfirmAdd'],
confirmAdd=dict['confirmAdd'],
healAdd=dict['healAdd'],
deadAdd=dict['deadAdd'],
)
print(f"{time.asctime()}插入数据完毕")
def insert_USA_history_confirm_data():
ls = get_USA_history_confirm_data()
print(f"{time.asctime()}开始插入美国历史疫情数据")
for i in ls :
ds = "2020." + i['date']
tup = time.strptime(ds, "%Y.%m.%d")
date = time.strftime("%Y-%m-%d", tup)
USA_history_confirm_data.objects.get_or_create(
date=date,
confirm = i['confirm'],
)
print(f"{time.asctime()}插入数据完毕")
def insert_usa_global_all_data():
ls = get_all_data()
print(f"{time.asctime()}开始插入美国和全球历史疫情数据")
for i in ls:
ds = "2020." + i[0]
tup = time.strptime(ds, "%Y.%m.%d")
date = time.strftime("%Y-%m-%d", tup)
usa_global_all_data.objects.get_or_create(
date=date,
usaconfirm=i[1],
confirm=i[2],
dead=i[3],
heal=i[4],
confirmAdd=i[5]
)
print(f"{time.asctime()}插入数据完毕")
def selectData_ByDate(select_date,top):
#根据选择的日期,返回(显示)排名前五的国家疫情数据 (国家名一个列表,每种数据一个列表)
datas = foreign_data.objects.filter(date=select_date).order_by('-confirm')[0:top]
# print(datas[0].name) #美国
ls_name = []
ls_confirm = []
ls_dead = []
ls_heal = []
ls_confirmAdd = []
ls_nowConfirm = []
for i in datas:
ls_name.append(i.name)
ls_confirm.append(i.confirm)
ls_dead.append(i.dead)
ls_heal.append(i.heal)
ls_confirmAdd.append(i.confirmAdd)
ls_nowConfirm.append(i.nowConfirm)
return {'ls_name':ls_name,'ls_confirm':ls_confirm,'ls_dead':ls_dead,'ls_heal':ls_heal,'ls_confirmAdd':ls_confirmAdd,'ls_nowConfirm':ls_nowConfirm}
在templates文件夹中创建一个名为‘index’的html文件
<html style="height: 100%">
<head>
<meta charset="UTF-8">
<title>疫情数据显示title>
head>
<body style="height: 100%; margin: 0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js">script>
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=xfhhaTThl11qYVrqLZii6w8qE5ggnhrY&__ec_v__=20190126">script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js">script>
<div>
<form method="post">
<h3>1.将最新疫情数据存入数据库h3>
<select name="Refresh">
<option value="Refresh">刷新option>
<option value="noRefresh">不刷新option>
select>
<input type="submit" value="选择">
form>
div>
<h3>2.查看国外疫情数据h3>
来源:数据库---时间范围:[6.27,今天] (中间有几天忘记存了,会没有数据)<br>
请选择:<br>
<form method="post">
日期:<input type="text" id="test11" name="selectDate">
Top(请输入数字):<input type="text" name="top">
{# 选择日期看 #}
<input type="submit" value="查看">
form>
<script src="../static/laydate/laydate.js">script>
<script>
//执行一个laydate实例,选择日期时出现日历形式
//自定义格式
laydate.render({
elem: '#test11'
,format: 'yyyy-MM-dd'
,done: function(value) {
{#alert(value); //得到日期生成的值,如:2017-08-18#}
}
});
script>
<p>查看 日期:{{ selectDate }},疫情严重程度 Top:{{ top_str }}国家的疫情数据:p>
<div id="container1" style="height: 100%">div>
<script type="text/javascript">
var dom = document.getElementById("container1");
var myChart = echarts.init(dom);
var app = {};
option = null;
option = {
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
data: ['确诊', '死亡', '治愈', '新增确诊', '现存确诊']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: {{foregin_name|safe}} // 后台views中返回的数据,|safe表示禁用转义,告诉模板这个变量是安全的,可以解释执行
},
series: [
{
name: '确诊',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'insideRight'
},
data: {{foregin_confirm}}
},
{
name: '死亡',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'insideRight'
},
data: {{foregin_dead}}
},
{
name: '治愈',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'insideRight'
},
data: {{foregin_heal}}
},
{
name: '新增确诊',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'insideRight'
},
data: {{foregin_confirmAdd}}
},
{
name: '现存确诊',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'insideRight'
},
data: {{foregin_nowConfirm}}
}
]
};;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
script>
<h3>3.历史疫情数据趋势图h3>
<div id="container" style="height: 100%">div>
<script type="text/javascript">
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
option = null;
option = {
title: {
text: '历史疫情数据'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['美国确诊','全球确诊','全球死亡','全球治愈','全球新增']
{# 线 #}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: {{all_date|safe}},
name: '日期'
},
yAxis: {
type: 'value',
name:'人数'
},
series: [
{
name: '美国确诊',
type: 'line',
stack: '美国确诊',
data: {{USA_history_confirm}}
},
{
name: '全球确诊',
type: 'line',
stack: '全球确诊',
data: {{all_confirm}}
},
{
name: '全球死亡',
type: 'line',
stack: '全球死亡',
data: {{all_dead}}
},
{
name: '全球治愈',
type: 'line',
stack: '全球治愈',
data: {{all_heal}}
},
{
name: '全球新增',
type: 'line',
stack: '全球新增',
data: {{all_confirmAdd}}
}
]
};
;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
script>
<h3>4.今日top 3Dh3>
<form method="post">
top(请输入数字):
<input type="submit">
form>
<p>top:{{ n_str }} , 国家:{{ topname|safe }}p>
<div id="3d" style="height: 100%">div>
<script type="text/javascript">
var dom = document.getElementById("3d");
var myChart = echarts.init(dom);
var app = {};
option = null;
var nation = {{topname|safe}};
var data_type = ['确诊', '死亡', '治愈',
'新增确诊', '现存确诊'];
var data = {{ topdata|safe }};
option = {
tooltip: {},
visualMap: {
max: 20,
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
}
},
xAxis3D: {
type: 'category',
data: data_type
},
yAxis3D: {
type: 'category',
data: nation
},
zAxis3D: {
type: 'value'
},
grid3D: {
boxWidth: 200,
boxDepth: 80,
light: {
main: {
intensity: 1.2
},
ambient: {
intensity: 0.3
}
}
},
series: [{
type: 'bar3D',
data: data.map(function (item) {
return {
value: [item[1], item[0], item[2]]
}
}),
shading: 'color',
label: {
show: false,
textStyle: {
fontSize: 16,
borderWidth: 1
}
},
itemStyle: {
opacity: 0.4
},
emphasis: {
label: {
textStyle: {
fontSize: 20,
color: '#900'
}
},
itemStyle: {
color: '#900'
}
}
}]
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
script>
#}
{#body>#}
{#html>#}
from django.shortcuts import render
from django.http import HttpRequest,HttpResponse
import jsonpath,datetime
from info.CrawlingDataUtils import get_USA_history_confirm_data,get_foreign_data,get_globalStatis_data,get_GlobalDailyList
from info.dbUtils import insert_foreign_data,insert_globalStatic,insert_usa_global_all_data,insert_USA_history_confirm_data,selectData_ByDate
# from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
def index(request):
#刷新按钮:爬取最新数据并插入到数据库中
Refresh = request.POST.get('Refresh') #根据表单中标签name
if Refresh == 'Refresh':
insert_USA_history_confirm_data()
insert_globalStatic()
insert_foreign_data()
insert_usa_global_all_data()
# nation = request.GET.getlist('nation')
selectDate = request.POST.get('selectDate')
top_str = request.POST.get('top')
# print(selectDate)
# print(type(selectDate)) #
#初次或未选择时,二者为None,进不去导致foregin_confirm等,没赋值导致context处出错
#先定义一个空列表
foregin_name = []
foregin_confirm = []
foregin_confirmAdd = []
foregin_heal = []
foregin_dead = []
foregin_nowConfirm = []
if (selectDate != None and top_str != None) and (selectDate != '' and top_str != ''):
top = int(str(top_str))
#选择日期将str转化成date
select_date = datetime.datetime.strptime(selectDate, '%Y-%m-%d').date()
foregin_dic = selectData_ByDate(select_date,top)
foregin_name = foregin_dic['ls_name']
foregin_confirm = foregin_dic['ls_confirm']
foregin_confirmAdd = foregin_dic['ls_confirmAdd']
foregin_heal = foregin_dic['ls_heal']
foregin_dead = foregin_dic['ls_dead']
foregin_nowConfirm = foregin_dic['ls_nowConfirm']
else:
selectDate = '____'
top_str = '____'
# print(type(selectDate))
#print(type(selectDate))
# 美国历史数据,最终目的返回 两个列表:USA_history_date、USA_history_confirm 供echarts使用
usaData = get_USA_history_confirm_data()
all_date = jsonpath.jsonpath(usaData, "$..date")
USA_history_confirm = jsonpath.jsonpath(usaData, "$..confirm")
#全球历史疫情数据
ls = get_GlobalDailyList()['ls']
today = get_GlobalDailyList()['today']
before_confirm = jsonpath.jsonpath(ls,"$..confirm")
before_dead = jsonpath.jsonpath(ls,"$..dead")
before_heal = jsonpath.jsonpath(ls,"$..heal")
before_newAddConfirm = jsonpath.jsonpath(ls,"$..newAddConfirm") #新增确诊
today_confirm = today['confirm']
today_dead = today['dead']
today_heal = today['heal']
today_confirmAdd = today['confirmAdd']
before_confirm.append(today_confirm)
# print(all_confirm):None append这个操作是没有返回值的(即返回一个None),b.append(a) append只更新b本身,正确的写法应该分开写:
before_dead.append(today_dead)
#all_dead = before_dead #before_dead 添加完today的数据,就为全的数据了 ==all_dead
before_heal.append(today_heal)
before_newAddConfirm.append(today_confirmAdd)
#当日外国数据 3d使用 整合坐标数据
n_str = request.POST.get('3dtop')
topdata = []
topname = []
if n_str != None and n_str != '' :
n = int(n_str)
topname = get_foreign_data()[0][0:n]#前n名 国家名字
topconfirm = get_foreign_data()[1][0:n]
topdead = get_foreign_data()[5][0:n]
topheal = get_foreign_data()[7][0:n]
topconfirmAdd = get_foreign_data()[2][0:n]
topnowConfirm = get_foreign_data()[9][0:n]
toplist = list(zip(topconfirm,topdead,topheal,topconfirmAdd,topnowConfirm))
for i in range(0,len(topname)):
# for j in : # 显示5个: ['确诊', '死亡', '治愈','新增确诊', '现存确诊'];
for j,k in zip(range(0, 5), toplist[i]): # python 如何在一个for循环中遍历两个列表,利用python自带的zip函数可同时对两个列表进行遍历,代码如下
temp = [i, j, k]
topdata.append(temp)
else:
n_str = '___'
context = {
#全球、美国 历史数据
'all_date':all_date,
'USA_history_confirm':USA_history_confirm,
'all_confirm':before_confirm,
'all_dead':before_dead,
'all_heal':before_heal,
'all_confirmAdd':before_newAddConfirm,
#选择日期,选择显示个数,显示外国疫情数据可视化
'selectDate':selectDate,
'top_str':top_str,
'foregin_name':foregin_name,
'foregin_confirm':foregin_confirm,
'foregin_confirmAdd':foregin_confirmAdd,
'foregin_heal':foregin_heal,
'foregin_dead':foregin_dead,
'foregin_nowConfirm':foregin_nowConfirm,
'topname':topname,
'topdata':topdata,
'n_str':n_str
}
return render(request,'index.html',context=context) #第二个参数表示返回的界面,第三个表示返回的数据(字典形式)