全球疫情可视化展示

  今天是一个缅怀在抗疫中牺牲烈士的日子。身为软工系的一名学生,应该做些东西!来纪念这次不一样的节日!

全球疫情数据可视化展示:

   网页地址:http://3031k7q292.qicp.vip/yiqing/WorldData.jsp

  (由于此web网站运用的是内网穿透访问,在服务器未开启的情况下无法访问网页)

一:任务目标

    1、实现全球疫情数据的爬取

    2、实现疫情数据的展示

    3、实现疫情数据可视化展示

    4、实现外网访问

二:效果图

 

 

  

 

 三:源代码

 

  JSP:

  1 <%@ page language="java" contentType="text/html; charset=UTF-8"
  2     pageEncoding="UTF-8"%>
  3 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  4 <%@page import="com.bean.Data" %>
  5 <!DOCTYPE html>
  6 <html>
  7 <head>
  8 <meta charset="ISO-8859-1">
  9 <title>世界疫情</title>
 10 </head>
 11 
 12 <meta charset="UTF-8">
 13      <link type="text/css" rel="stylesheet" href="css/style.css">
 14 <script src="js/jquery-3.4.1.min.js"></script>
 15 <script src="js/echarts.min.js"></script>
 16 <script src="js/world.js"></script>
 17 
 18     <style>
 19         *{margin:0;padding:0}
 20         html,body{
 21             width:100%;
 22             height:100%;
 23         }
 24         #main{
 25               width:1500px;
 26               height:1350px;
 27               margin: 450px auto;
 28               border:1px solid #ddd;
 29           }
 30         /*默认长宽比0.75*/
 31     </style>
 32 </head>
 33 
 34 <body onload="checkfind()">
 35 <br>
 36 <h1>疫情统计表</h1>
 37 <br>
 38 <br>
 39 <br>
 40 <div id="h">
 41 <span>
 42 <script>document.write(time);</script>
 43 </span>
 44 </div>
 45 
 46 <div id="table">
 47 
 48 
 49 
 50 </div>
 51   <div id="main">
 52   
 53   </div>
 54   <script type="text/javascript">
 55 
 56 
 57     function randomValue() {
 58         return Math.round(Math.random()*1000);
 59     }
 60     var dt;
 61     var data = new Array(0);
 62              myDate = new Date();
 63              var y = myDate.getFullYear();
 64              var m = myDate.getMonth()+1;//获取当前月份的日期
 65              if(m<10){
 66                  m='0'+m;
 67              }
 68              var d = myDate.getDate();
 69              if(d<10){
 70                     d='0'+d;
 71              }
 72              var time = y+"-"+m+"-"+d;
 73     $("#h").html(time);
 74     function checkfind() {
 75         
 76 
 77         if(time=="")
 78         {
 79             alert("请输入时间!");
 80             return ;
 81         }
 82         else{
 83             
 84 
 85             $.ajax({
 86                 url : "WorldDataServlet",
 87                 async : true,
 88                 type : "POST",
 89                 data : {
 90                     "time" : time
 91                 },
 92                 dataType : "json",
 93                 success : function(json) {
 94                     
 95                     
 96                     for (var i = 0; i < json.length; i++) {
 97                         var d = {};
 98                         
 99                         d["name"] = json[i].Province;
100                         d["value"] = json[i].Confirmed_num;
101                         d["yisi_num"] = json[i].Yisi_num;
102                         d["cured_num"] = json[i].Cured_num;
103                         d["dead_num"] = json[i].Dead_num;
104                         
105                         
106                         data.push(d);
107                     }
108                     
109                     
110                     var myChart = echarts.init(document.getElementById('main'));
111                     function randomValue() {
112                         return Math.round(Math.random()*1000);
113                     }
114                     var optionMap = {
115                             backgroundColor : '#FFFFFF',
116                             title : {
117                                 text : '世界疫情',
118                                 subtext : '',
119                                 x : 'center'
120                             },
121                             tooltip : {
122                                 formatter : function(params) {
123                                     return params.name + '<br/>' + '确诊人数 : '
124                                             + params.value + '<br/>' + '死亡人数 : '
125                                             + params['data'].dead_num + '<br/>' + '治愈人数 : '
126                                             + params['data'].cured_num + '<br/>'+ '疑似患者人数 : '
127                                             + params['data'].yisi_num;
128                                 }
129                             },
130 
131                             //左侧小导航图标
132                             visualMap: {
133                                 min: 0,
134                                 max: 350000,
135                                 left: 'left',
136                                 top: 'bottom',
137                                 text: ['',''],//取值范围的文字
138                                 inRange: {
139                                     color: ['yellow','orangered','red']//取值范围的颜色
140                                 },
141                                 show:true//图注
142                             },
143                       
144 
145                             //配置属性
146                             series : [ {
147                                 type : 'map',
148                                 mapType : 'world',
149                                 label : {
150                                     show : true
151                                 },
152 
153                                 zoom: 1, //当前视角的缩放比例
154 
155                                 roam: true, //是否开启平游或缩放
156 
157                                 scaleLimit: { //滚轮缩放的极限控制
158 
159                                   min: 1,
160 
161                                   max: 2
162 
163                                 },
164                                 data : data,
165                                 nameMap : {
166 
167                                    'Singapore Rep.':'新加坡',
168                                    'Dominican Rep.':'多米尼加',
169                                    'Palestine':'巴勒斯坦',
170                                    'Bahamas':'巴哈马',
171                                    'Timor-Leste':'东帝汶',
172                                    'Afghanistan':'阿富汗',
173                                    'Guinea-Bissau':'几内亚比绍',
174                                    "Côte d'Ivoire":'科特迪瓦',
175                                    'Siachen Glacier':'锡亚琴冰川',
176                                    "Br. Indian Ocean Ter.":'英属印度洋领土',
177                                    'Angola':'安哥拉',
178                                    'Albania':'阿尔巴尼亚',
179                                    'United Arab Emirates':'阿联酋',
180                                    'Argentina':'阿根廷',
181                                    'Armenia':'亚美尼亚',
182                                    'French Southern and Antarctic Lands':'法属南半球和南极领地',
183                                    'Australia':'澳大利亚',
184                                    'Austria':'奥地利',
185                                    'Azerbaijan':'阿塞拜疆',
186                                    'Burundi':'布隆迪',
187                                    'Belgium':'比利时',
188                                    'Benin':'贝宁',
189                                    'Burkina Faso':'布基纳法索',
190                                    'Bangladesh':'孟加拉国',
191                                    'Bulgaria':'保加利亚',
192                                    'The Bahamas':'巴哈马',
193                                    'Bosnia and Herz.':'波斯尼亚和黑塞哥维那',
194                                    'Belarus':'白俄罗斯',
195                                    'Belize':'伯利兹',
196                                    'Bermuda':'百慕大',
197                                    'Bolivia':'玻利维亚',
198                                    'Brazil':'巴西',
199                                    'Brunei':'文莱',
200                                    'Bhutan':'不丹',
201                                    'Botswana':'博茨瓦纳',
202                                    'Central African Rep.':'中非',
203                                    'Canada':'加拿大',
204                                    'Switzerland':'瑞士',
205                                    'Chile':'智利',
206                                    'China':'中国',
207                                    'Ivory Coast':'象牙海岸',
208                                    'Cameroon':'喀麦隆',
209                                    'Dem. Rep. Congo':'刚果民主共和国',
210                                    'Congo':'刚果',
211                                    'Colombia':'哥伦比亚',
212                                    'Costa Rica':'哥斯达黎加',
213                                    'Cuba':'古巴',
214                                    'N. Cyprus':'北塞浦路斯',
215                                    'Cyprus':'塞浦路斯',
216                                    'Czech Rep.':'捷克',
217                                    'Germany':'德国',
218                                    'Djibouti':'吉布提',
219                                    'Denmark':'丹麦',
220                                    'Algeria':'阿尔及利亚',
221                                    'Ecuador':'厄瓜多尔',
222                                    'Egypt':'埃及',
223                                    'Eritrea':'厄立特里亚',
224                                    'Spain':'西班牙',
225                                    'Estonia':'爱沙尼亚',
226                                    'Ethiopia':'埃塞俄比亚',
227                                    'Finland':'芬兰',
228                                    'Fiji':'',
229                                    'Falkland Islands':'福克兰群岛',
230                                    'France':'法国',
231                                    'Gabon':'加蓬',
232                                    'United Kingdom':'英国',
233                                    'Georgia':'格鲁吉亚',
234                                    'Ghana':'加纳',
235                                    'Guinea':'几内亚',
236                                    'Gambia':'冈比亚',
237                                    'Guinea Bissau':'几内亚比绍',
238                                    'Eq. Guinea':'赤道几内亚',
239                                    'Greece':'希腊',
240                                    'Greenland':'格陵兰',
241                                    'Guatemala':'危地马拉',
242                                    'French Guiana':'法属圭亚那',
243                                    'Guyana':'圭亚那',
244                                    'Honduras':'洪都拉斯',
245                                    'Croatia':'克罗地亚',
246                                    'Haiti':'海地',
247                                    'Hungary':'匈牙利',
248                                    'Indonesia':'印度尼西亚',
249                                    'India':'印度',
250                                    'Ireland':'爱尔兰',
251                                    'Iran':'伊朗',
252                                    'Iraq':'伊拉克',
253                                    'Iceland':'冰岛',
254                                    'Israel':'以色列',
255                                    'Italy':'意大利',
256                                    'Jamaica':'牙买加',
257                                    'Jordan':'约旦',
258                                    'Japan':'日本',
259                                    'Kazakhstan':'哈萨克斯坦',
260                                    'Kenya':'肯尼亚',
261                                    'Kyrgyzstan':'吉尔吉斯斯坦',
262                                    'Cambodia':'柬埔寨',
263                                    'Korea':'韩国',
264                                    'Kosovo':'科索沃',
265                                    'Kuwait':'科威特',
266                                    'Lao PDR':'老挝',
267                                    'Lebanon':'黎巴嫩',
268                                    'Liberia':'利比里亚',
269                                    'Libya':'利比亚',
270                                    'Sri Lanka':'斯里兰卡',
271                                    'Lesotho':'莱索托',
272                                    'Lithuania':'立陶宛',
273                                    'Luxembourg':'卢森堡',
274                                    'Latvia':'拉脱维亚',
275                                    'Morocco':'摩洛哥',
276                                    'Moldova':'摩尔多瓦',
277                                    'Madagascar':'马达加斯加',
278                                    'Mexico':'墨西哥',
279                                    'Macedonia':'马其顿',
280                                    'Mali':'马里',
281                                    'Myanmar':'缅甸',
282                                    'Montenegro':'黑山',
283                                    'Mongolia':'蒙古',
284                                    'Mozambique':'莫桑比克',
285                                    'Mauritania':'毛里塔尼亚',
286                                    'Malawi':'马拉维',
287                                    'Malaysia':'马来西亚',
288                                    'Namibia':'纳米比亚',
289                                    'New Caledonia':'新喀里多尼亚',
290                                    'Niger':'尼日尔',
291                                    'Nigeria':'尼日利亚',
292                                    'Nicaragua':'尼加拉瓜',
293                                    'Netherlands':'荷兰',
294                                    'Norway':'挪威',
295                                    'Nepal':'尼泊尔',
296                                    'New Zealand':'新西兰',
297                                    'Oman':'阿曼',
298                                    'Pakistan':'巴基斯坦',
299                                    'Panama':'巴拿马',
300                                    'Peru':'秘鲁',
301                                    'Philippines':'菲律宾',
302                                    'Papua New Guinea':'巴布亚新几内亚',
303                                    'Poland':'波兰',
304                                    'Puerto Rico':'波多黎各',
305                                    'Dem. Rep. Korea':'朝鲜',
306                                    'Portugal':'葡萄牙',
307                                    'Paraguay':'巴拉圭',
308                                    'Qatar':'卡塔尔',
309                                    'Romania':'罗马尼亚',
310                                    'Russia':'俄罗斯',
311                                    'Rwanda':'卢旺达',
312                                    'W. Sahara':'西撒哈拉',
313                                    'Saudi Arabia':'沙特阿拉伯',
314                                    'Sudan':'苏丹',
315                                    'S. Sudan':'南苏丹',
316                                    'Senegal':'塞内加尔',
317                                    'Solomon Is.':'所罗门群岛',
318                                    'Sierra Leone':'塞拉利昂',
319                                    'El Salvador':'萨尔瓦多',
320                                    'Somaliland':'索马里兰',
321                                    'Somalia':'索马里',
322                                    'Serbia':'塞尔维亚',
323                                    'Suriname':'苏里南',
324                                    'Slovakia':'斯洛伐克',
325                                    'Slovenia':'斯洛文尼亚',
326                                    'Sweden':'瑞典',
327                                    'Swaziland':'斯威士兰',
328                                    'Syria':'叙利亚',
329                                    'Chad':'乍得',
330                                    'Togo':'多哥',
331                                    'Thailand':'泰国',
332                                    'Tajikistan':'塔吉克斯坦',
333                                    'Turkmenistan':'土库曼斯坦',
334                                    'East Timor':'东帝汶',
335                                    'Trinidad and Tobago':'特里尼达和多巴哥',
336                                    'Tunisia':'突尼斯',
337                                    'Turkey':'土耳其',
338                                    'Tanzania':'坦桑尼亚',
339                                    'Uganda':'乌干达',
340                                    'Ukraine':'乌克兰',
341                                    'Uruguay':'乌拉圭',
342                                    'United States':'美国',
343                                    'Uzbekistan':'乌兹别克斯坦',
344                                    'Venezuela':'委内瑞拉',
345                                    'Vietnam':'越南',
346                                    'Vanuatu':'瓦努阿图',
347                                    'West Bank':'西岸',
348                                    'Yemen':'也门',
349                                    'South Africa':'南非',
350                                    'Zambia':'赞比亚',
351                                    'Zimbabwe':'津巴布韦'
352                                 }
353 
354                             } ]
355                         };
356                         myChart.setOption(optionMap);
357                         myChart.on('click', function (params) {
358                             alert(params.name);
359                         });
360 
361                    
362                     alert("成功!");
363                     
364                    
365         //使用制定的配置项和数据显示图表
366                 createShowingTable(json);
367    
368                 },
369                 error : function() {
370                     alert("请求失败");
371                 },
372            });
373     }
374          
375     }        
376   /*  setTimeout(function () {
377         myChart.setOption({
378             series : [
379                 {
380                     name: '信息量',
381                     type: 'map',
382                     geoIndex: 0,
383                     data:dataList
384                 }
385             ]
386         });
387     },1000)*/
388     function createShowingTable(json) {
389          var tableStr = "<table id='gradient-style' style='background-color:blue; width:100%; height:100%'>";
390          tableStr = tableStr
391            + "<tr>"
392            
393            +"<td >国家</td>"
394            +"<td >确诊人数</td>"
395            +"<td >疑似人数</td>"
396            +"<td >治愈人数</td>"
397            +"<td >死亡人数</td>"
398            +"</tr>";
399          var len = data.length;
400          for ( var i = 0; i < len; i++) {
401           tableStr = tableStr + "<tr>"
402             
403             +"<td>"+ json[i].Province +"</td>"
404             +"<td>"+ json[i].Confirmed_num + "</td>"
405             + "<td>"+ json[i].Yisi_num + "</td>"
406             + "<td>"+ json[i].Cured_num + "</td>"
407             +"<td>"+json[i].Dead_num+"</td>"
408             +"</tr>";
409          }
410 
411          tableStr = tableStr + "</table>";
412          //添加到div中
413          $("#table").html(tableStr);1
414   }
415 
416 </script>
417     
418 
419 </body>
420 </html>
WorldData.jsp

 

  Python爬虫源码:

import json

import numpy as np
import pymysql
import requests
from bs4 import BeautifulSoup
import datetime

url = 'https://ncov.dxy.cn/ncovh5/view/pneumonia?from=timeline&isappinstalled=0'  #请求地址
headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'}#创建头部信息
response =  requests.get(url,headers = headers)  #发送网络请求
#print(response.content.decode('utf-8'))#以字节流形式打印网页源码
content = response.content.decode('utf-8')
#print(content)
soup = BeautifulSoup(content, 'html.parser')
listA = soup.find_all(name='script',attrs={"id":"getAreaStat"})
#世界确诊getAreaStat
listB = soup.find_all(name='script',attrs={"id":"getListByCountryTypeService2true"})
#listA = soup.find_all(name='div',attrs={"class":"c-touchable-feedback c-touchable-feedback-no-default"})
account = str(listA)
world_messages = str(listB)[95:-21]
messages = account[52:-21]
messages_json = json.loads(messages)
print(world_messages)
world_messages_json = json.loads(world_messages)
valuesList = []
cityList = []
worldList = []
now_time = datetime.datetime.now().strftime('%Y-%m-%d')

for k in range(len(world_messages_json)):
    worldvalue = (now_time,
             world_messages_json[k].get('countryType'),world_messages_json[k].get('continents'),world_messages_json[k].get('provinceId'),world_messages_json[k].get('provinceName'),
             world_messages_json[k].get('provinceShortName'),world_messages_json[k].get('cityName'),world_messages_json[k].get('currentConfirmedCount'),world_messages_json[k].get('confirmedCount'),
             world_messages_json[k].get('suspectedCount'),world_messages_json[k].get('curedCount'),world_messages_json[k].get('deadCount'),world_messages_json[k].get('locationId'),
             world_messages_json[k].get('countryShortCode'),)
    worldList.append(worldvalue)
for i in range(len(messages_json)):
    #value = messages_json[i]
    value = (now_time,messages_json[i].get('provinceName'),messages_json[i].get('provinceShortName'),messages_json[i].get('currentConfirmedCount'),messages_json[i].get('confirmedCount'),messages_json[i].get('suspectedCount'),messages_json[i].get('curedCount'),messages_json[i].get('deadCount'),messages_json[i].get('comment'),messages_json[i].get('locationId'),messages_json[i].get('statisticsData'))
    valuesList.append(value)
    cityValue = messages_json[i].get('cities')
    #print(cityValue)
    for j in range(len(cityValue)):
        cityValueList = (cityValue[j].get('cityName'),cityValue[j].get('currentConfirmedCount'),cityValue[j].get('confirmedCount'),cityValue[j].get('suspectedCount'),cityValue[j].get('curedCount'),cityValue[j].get('deadCount'),cityValue[j].get('locationId'),messages_json[i].get('provinceShortName'))
        #print(cityValueList)
        cityList.append(cityValueList)
    #cityList.append(cityValue)
db = pymysql.connect("localhost", "root", "123456", "mytest", charset='utf8')
cursor = db.cursor()
array = np.asarray(valuesList[0])
#sql_clean_world = "TRUNCATE TABLE world_map"
sql_clean_city = "TRUNCATE TABLE city_map"
sql_clean_json = "TRUNCATE TABLE province_data_from_json"
sql_clean_province = "TRUNCATE TABLE province_map"
sql_clean_world = "TRUNCATE TABLE world_map"
sql1 = "INSERT INTO city_map values (%s,%s,%s,%s,%s,%s,%s,%s)"
sql_world = "INSERT INTO world_map values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
#sql = "INSERT INTO province_map values (0,'%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') "
sql = "INSERT INTO province_map values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) "
#sql = "INSERT INTO province_map (provinceName,provinceShortName,correntConfirmedCount,confirmedCount,suspectedCount,curedCount,deadCount,comment,locationId,statisticsData) values (0,'%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') "
#sql = """INSERT INTO province_map (provinceName,provinceShortName,correntConfirmedCount,confirmedCount,suspectedCount,curedCount,deadCount,comment,locationId,statisticsData) values ('湖北省', '湖北', 43334, 64786, 0, 18889, 2563, '', 420000, 'https://file1.dxycdn.com/2020/0223/618/3398299751673487511-135.json')"""
value_tuple = tuple(valuesList)
cityTuple = tuple(cityList)
worldTuple = tuple(worldList)
print(worldTuple)
print(tuple(value_tuple))
try:
    #cursor.execute(sql_clean_city)
    #cursor.execute(sql_clean_province)
    #cursor.executemany(sql, value_tuple)
    #cursor.executemany(sql1,cityTuple)
    db.commit()
except:
    print('执行失败,进入回调1')
    db.rollback()

try:
    #cursor.execute(sql_clean_city)
    #cursor.execute(sql_clean_province)
    #cursor.execute(sql_clean_world)
    #cursor.executemany(sql, value_tuple)
    #cursor.executemany(sql1,cityTuple)
    cursor.executemany(sql_world, worldTuple)
    db.commit()
except:
    print('执行失败,进入回调2')
    db.rollback()
try:
    #cursor.execute(sql_clean_city)
    #cursor.execute(sql_clean_province)
    cursor.executemany(sql, value_tuple)
    #cursor.executemany(sql1,cityTuple)
    db.commit()
except:
    print('执行失败,进入回调3')
    db.rollback()

try:
    #cursor.execute(sql_clean_city)
    #cursor.execute(sql_clean_province)
    #cursor.executemany(sql, value_tuple)
    #cursor.executemany(sql1,cityTuple)
    db.commit()
except:
    print('执行失败,进入回调4')
    db.rollback()
#print(messages_json)
#print(account[52:-21])
# soupDiv = BeautifulSoup(listA,'html.parser')
# listB = soupDiv.find_all(name='div',attrs={"class":"c-gap-bottom-zero c-line-clamp2"})
#for i in listA:
    #print(i)
#listA[12]
#print(listA)


db.close()
爬虫

 

四:遇到的问题

   首先是world.js资源难找,附上我的资源链接:

   https://pan.baidu.com/s/1tZkCm06wZpfH4MBvf9gDnw 提取码: bvy3 

   然后就是CSS部分学的不太好,导致未能达到预期效果

 

五:时间表

习时长 6h
预计时常 8h
实际时常 10h
知识点 内网穿透

 

posted @ 2020-04-04 22:57  邵文  阅读(1028)  评论(0编辑  收藏  举报