说明
之前也看过许多朋友用python绘制疫情地图,看着是不难,但是都没有绘制过,这怎么行呢,必须得自己也体验一把,过过瘾。所以就抓取最新的疫情数据,进行可视化绘图,写这篇文章其实没什么特别要说明的知识点,主要是想记录一下自己的敲代码时光,另一方面就是为了养成一种坚持写文章的习惯。
数据来源
首先这个数据是来源于腾讯新闻的,进入网页主界面,找到抗肺炎,点击右边的疫情实时追踪,就会跳转到新的页面。
然后点击海外疫情,往下滑动,找到如下图所示数据
通过点击鼠标右键检查,找到相对应的数据来源,我们发现在途中所标记的红线框内有我们想要的数据,
点击Headers,出现如下所示的内容,对目标url进行分析,里面包含了callback的值和时间戳,因此我们要够造对应的url。
callback里面的值跟上面目标url里面的JQuery的后面是一样的,所以我们就可以构造出正确的目标url。
目标url的确定
构造时间戳
# 构造时间戳
import time
import math
start_time = time.time()
# 构建时间戳
real_time = math.ceil(start_time*1000)
print(real_time)
设置请求头
# 请求头
headers1 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36',
'callable':'jQuery35108410968089910225_1605792552348'}
构造最终目标网页url
# 通过对网页的分析,确定目标url的格式
# 构造目标url
url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign&callback=jQuery{}'.format(headers1["callable"])+"&_="+str(real_time)
代码描述
导入相关的库并构造目标url
import time
import math
import requests
import json
# 导入绘图所用的库
from pyecharts.charts import Map,Geo
from pyecharts import options as opts
start_time = time.time()
# 构建时间戳
real_time = math.ceil(start_time*1000)
# 请求头
headers1 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36',
'callable':'jQuery35108410968089910225_1605792552348'}
# 通过对网页的分析,确定目标url的格式
# 构造目标url
url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign&callback={}'.format(headers1["callable"])+"&_="+str(real_time)
# page_data = requests.get(url,headers = headers1)
获取网页信息
# 对目标网址发起requests请求
data = requests.post(url=url,headers = headers1)
# 对获取到的网页内容进行编码转换
data.encoding = data.apparent_encoding
data1 = data.text
# 查看获取到的内容
data1
获取到的数据展示如下
由途中的数据格式我们发现,这是json格式的数据,所以我们需要对json格式的数据进行数据类型转换,然后再提取。转换为python可交互的数据类型,不难发现这是字典格式的数据,因此我们要提取值,就要通过字典的键来获取。我们想要的数据是在data这个键里面,所以就按照字典获取键值的方式进行获取。
#数据类型转换
# 将数据类型转换为python可交互的格式
json_data = json.loads(data1)
#提取数据
info = json_data["data"]
info
提取到的数据如下:
经过提取后,发现每个国家的数据信息是在一个列表里面的,然后每个国家又是一个单独的字典,所以我们要获取每个国家的数据,就通过列表的遍历轮询来进行获取。
# 创建一个空列表,用来装每个国家的相关数据
info_list = []
# 遍历轮询每个国家的信息
for country in info:
# 提取国家名称
name = country["name"]
# 提取每个国家的确诊人数
confirm = country["confirm"]
#把每个国家和确诊人数放在一个元组里,然后添加到列表中
info_tuple = (name,confirm)
info_list.append(info_tuple)
# data_list = zip(name,confirm)
# 展示提取后的效果
info_list
提取后的数据格式和效果展示
可视化过程
绘图前准备
现在数据已经拿到了,接下来就是可视化过程
下面这个中英文国家名称映射表是从https://blog.csdn.net/llllllkkkkkooooo/article/details/107431181这篇文章中copy过来的,在这里对这位博主深表感谢
#国家名称表中英文到中文的映射
nameMap = {
'Singapore Rep.':'新加坡',
'Dominican Rep.':'多米尼加',
'Palestine':'巴勒斯坦',
'Bahamas':'巴哈马',
'Timor-Leste':'东帝汶',
'Afghanistan':'阿富汗',
'Guinea-Bissau':'几内亚比绍',
"Côte d'Ivoire":'科特迪瓦',
'Siachen Glacier':'锡亚琴冰川',
"Br. Indian Ocean Ter.":'英属印度洋领土',
'Angola':'安哥拉',
'Albania':'阿尔巴尼亚',
'United Arab Emirates':'阿联酋',
'Argentina':'阿根廷',
'Armenia':'亚美尼亚',
'French Southern and Antarctic Lands':'法属南半球和南极领地',
'Australia':'澳大利亚',
'Austria':'奥地利',
'Azerbaijan':'阿塞拜疆',
'Burundi':'布隆迪',
'Belgium':'比利时',
'Benin':'贝宁',
'Burkina Faso':'布基纳法索',
'Bangladesh':'孟加拉国',
'Bulgaria':'保加利亚',
'The Bahamas':'巴哈马',
'Bosnia and Herz.':'波斯尼亚和黑塞哥维那',
'Belarus':'白俄罗斯',
'Belize':'伯利兹',
'Bermuda':'百慕大',
'Bolivia':'玻利维亚',
'Brazil':'巴西',
'Brunei':'文莱',
'Bhutan':'不丹',
'Botswana':'博茨瓦纳',
'Central African Rep.':'中非',
'Canada':'加拿大',
'Switzerland':'瑞士',
'Chile':'智利',
'China':'中国',
'Ivory Coast':'象牙海岸',
'Cameroon':'喀麦隆',
'Dem. Rep. Congo':'刚果民主共和国',
'Congo':'刚果',
'Colombia':'哥伦比亚',
'Costa Rica':'哥斯达黎加',
'Cuba':'古巴',
'N. Cyprus':'北塞浦路斯',
'Cyprus':'塞浦路斯',
'Czech Rep.':'捷克',
'Germany':'德国',
'Djibouti':'吉布提',
'Denmark':'丹麦',
'Algeria':'阿尔及利亚',
'Ecuador':'厄瓜多尔',
'Egypt':'埃及',
'Eritrea':'厄立特里亚',
'Spain':'西班牙',
'Estonia':'爱沙尼亚',
'Ethiopia':'埃塞俄比亚',
'Finland':'芬兰',
'Fiji':'斐',
'Falkland Islands':'福克兰群岛',
'France':'法国',
'Gabon':'加蓬',
'United Kingdom':'英国',
'Georgia':'格鲁吉亚',
'Ghana':'加纳',
'Guinea':'几内亚',
'Gambia':'冈比亚',
'Guinea Bissau':'几内亚比绍',
'Eq. Guinea':'赤道几内亚',
'Greece':'希腊',
'Greenland':'格陵兰',
'Guatemala':'危地马拉',
'French Guiana':'法属圭亚那',
'Guyana':'圭亚那',
'Honduras':'洪都拉斯',
'Croatia':'克罗地亚',
'Haiti':'海地',
'Hungary':'匈牙利',
'Indonesia':'印度尼西亚',
'India':'印度',
'Ireland':'爱尔兰',
'Iran':'伊朗',
'Iraq':'伊拉克',
'Iceland':'冰岛',
'Israel':'以色列',
'Italy':'意大利',
'Jamaica':'牙买加',
'Jordan':'约旦',
'Japan':'日本',
'Japan':'日本本土',
'Kazakhstan':'哈萨克斯坦',
'Kenya':'肯尼亚',
'Kyrgyzstan':'吉尔吉斯斯坦',
'Cambodia':'柬埔寨',
'Korea':'韩国',
'Kosovo':'科索沃',
'Kuwait':'科威特',
'Lao PDR':'老挝',
'Lebanon':'黎巴嫩',
'Liberia':'利比里亚',
'Libya':'利比亚',
'Sri Lanka':'斯里兰卡',
'Lesotho':'莱索托',
'Lithuania':'立陶宛',
'Luxembourg':'卢森堡',
'Latvia':'拉脱维亚',
'Morocco':'摩洛哥',
'Moldova':'摩尔多瓦',
'Madagascar':'马达加斯加',
'Mexico':'墨西哥',
'Macedonia':'马其顿',
'Mali':'马里',
'Myanmar':'缅甸',
'Montenegro':'黑山',
'Mongolia':'蒙古',
'Mozambique':'莫桑比克',
'Mauritania':'毛里塔尼亚',
'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':'巴拉圭',
'Qatar':'卡塔尔',
'Romania':'罗马尼亚',
'Russia':'俄罗斯',
'Rwanda':'卢旺达',
'W. Sahara':'西撒哈拉',
'Saudi Arabia':'沙特阿拉伯',
'Sudan':'苏丹',
'S. Sudan':'南苏丹',
'Senegal':'塞内加尔',
'Solomon Is.':'所罗门群岛',
'Sierra Leone':'塞拉利昂',
'El Salvador':'萨尔瓦多',
'Somaliland':'索马里兰',
'Somalia':'索马里',
'Serbia':'塞尔维亚',
'Suriname':'苏里南',
'Slovakia':'斯洛伐克',
'Slovenia':'斯洛文尼亚',
'Sweden':'瑞典',
'Swaziland':'斯威士兰',
'Syria':'叙利亚',
'Chad':'乍得',
'Togo':'多哥',
'Thailand':'泰国',
'Tajikistan':'塔吉克斯坦',
'Turkmenistan':'土库曼斯坦',
'East Timor':'东帝汶',
'Trinidad and Tobago':'特里尼达和多巴哥',
'Tunisia':'突尼斯',
'Turkey':'土耳其',
'Tanzania':'坦桑尼亚',
'Uganda':'乌干达',
'Ukraine':'乌克兰',
'Uruguay':'乌拉圭',
'United States':'美国',
'Uzbekistan':'乌兹别克斯坦',
'Venezuela':'委内瑞拉',
'Vietnam':'越南',
'Vanuatu':'瓦努阿图',
'West Bank':'西岸',
'Yemen':'也门',
'South Africa':'南非',
'Zambia':'赞比亚',
'Zimbabwe':'津巴布韦'
}
设置每个区间的范围
#自定义的每一段的取值范围
during = [
{"min":10000000},
{"min": 1000000, "max":9999999},
{"min": 100000, "max": 999999},
{"min": 10000, "max": 99999},
{"min": 1000, "max": 9999},
{"min":0,"max":999},
]
绘图阶段
设置图形的参数
#width:地图的宽度,height:地图的高度,page_title:地图的标题
map = Map(opts.InitOpts(width='1650px',height='890px')).add(series_name="最新世界疫情分布情况",
# 要展示的数据项
data_pair=info_list,
# 地图类型为世界地图
maptype="world",
# 自定义读取的名称的映射
name_map=nameMap,
# 是否显示标记图形
is_map_symbol_show=False)
# label_opts:标签配置项设置,is_show:是否显示视觉映射配置
map.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
将设置好的参数带入到绘图函数中进行绘图
#is_piecewise:是否为分段展示,pieces:设置每一个区间的范围
#max_:设置 visualMapPiecewise 所有取值区间中的最大值,TitleOpts:标题设置
map.set_global_opts(
title_opts=opts.TitleOpts(pos_left="80px",title="世界疫情分布情况地图",subtitle_textstyle_opts=opts.TextStyleOpts(font_size=20)),
legend_opts=opts.LegendOpts(selected_mode='multiple'),
visualmap_opts=opts.VisualMapOpts(max_=10000000,is_piecewise=True,pieces=during),
)
map.render("世界疫情分布情况地图.html")
这样,我们的世界疫情地图就绘制好了,来看看这个效果吧
从图中可以看出,美利坚果然不负众望,登顶世界第一。
网页展示效果在这里
感谢这位博主,绘图的很多参数都是看他的操作的https://blog.csdn.net/llllllkkkkkooooo/article/details/107431181