疫情数据获取 – 爬虫(requests,pandas,json)
一、网站链接:
https://wp.m.163.com/163/page/news/virus_report/index.html?nw=1&anw=1
二、 操作步骤:
1.打开开发者工具(在网页浏览器中打开网址,按f12即可)
2.选择‘network’面板,设置类型为‘xhr’类型,刷新页面
3.点击以‘list-total’开头的链接,查看headers和preview面板
headers中是网页头文件信息(包含:通用,响应,请求)
preview中是我们要获取的具体数据信息
三、使用爬虫requests请求库,获取preview面板中的数据信息
1.获取数据信息的网址(url)(Headers-General-Request URL)
url:https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=319439847098
2.向服务器发送请求(Headers-General-Request Method:get 方式请求)
请求方式常用的有:get 和 post
3.请求状态码为200时,表示请求成功(Headers-General-Status Code:200)
4.user-agent:客户端信息(这个随便从网上搜就可以了,目的就是告诉服务器我是浏览器而不是爬虫)
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
#代码如下:
import requests #导入请求库
ua = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0"} #请求时,提交给服务器的客户端信息user-agent
url = "https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=319439847098" #要请求的url
resp_data = requests.get(url,headers = ua) #请求语句
print(resp_data.status_code) #打印请求状态码,200时表示成功
print(resp_data.text) #打印请求的数据
四、本例中爬取数据后的相关操作
1) 将字符串与其它格式之间相互转换(使用json库)
import json
json.dumps(字典) #将字典转换为字符串
json.loads(字符串) #将字符串转换为字典
2) python中字典容器对象的使用
字典键,值,键值对的获取 keys(),values(),items()
字典元素的访问 用键访问,用get访问
3) pandas中,怎么将字典转换为dataframe格式的数据
import pandas as pd
pd.DataFrame([字典1,字典2,字典3])
4) 将dataframe格式的数据保存到本地的csv格式文件
df.to_csv("文件名.csv")
注意格式:gbk utf-8 utf-8-sig
5) 合并多个df为1个df
pd.concat([df列表],axis=1) axis为1时,是横向合并
6) pandas中设置行索引的命令
df.set_index(关键字)
df.reset_index(drop=True) #重新设置行索引,删除原来的索引列
7) pandas中插入列的操作
df.insert(位置,列名,数据)
8) pandas中删除列的操作
df.drop(列名,axis=1)
# 功能1-疫情数据获取代码
import requests #导入请求库
import pandas as pd #导入pandas库,另命名为pd
import json #导入json库,进行字符串与字典的转换
#函数1:请求url函数
def url_def(url):
#请求时,提交给服务器的客户端信息user-agent
ua = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0"}
resp_data = requests.get(url,headers = ua)
# print(resp_data.status_code) #打印请求状态码,结果为200时表示成功
return resp_data.text #返回请求的数据,打印结果为字符串(str)
#函数2:获取data数据
def data_def(html):
dic_data1 = json.loads(html) #将字符串转换为字典,dumps为将字典转换为字符串
#访问数据中的data信息
data_v1 = dic_data1['data']
return data_v1
# data中包含的键有:
# areaTree 全球实时数据
# chinaDayList 中国历史数据
# chinaTotal 中国实时数据
# lastUpdateTime 最后的更新时间
# overseaLastUpdateTime 海外的最后的更新时间
# 函数3 中国实时数据
def china_real_def(data_v1):
china_real_data = data_v1['chinaTotal'] #中国实时数据
# pd.DataFrame(china_real_data) #利用DataFrame数据框,将字典转化为dataframe格式的数据
return china_real_data
#函数4 全球实时数据
def area_real_def(data_v1,i):
real_data = data_v1['areaTree'][i] #全球实时数据
return real_data
#函数5:中国历史数据
def china_hist_def(data_v1,i):
hist_data = data_v1['chinaDayList'][i]
return hist_data
#函数6:全球每个国家各省份的实时数据
def country_real_def(data_v1,k,i):
hist_data = data_v1['areaTree'][k]['children'][i]
return hist_data
# 功能函数1:转换中英文,并转换为df
def change_def(china_real_data):
#建立中英文对照关系的字典
cn_en_dic = {'confirm': "确诊", 'suspect': "疑似", 'heal': "治愈", 'dead': "死亡", 'severe':"重症",
'storeConfirm': "现存确诊", 'input': "输入",'noSymptom': "无症状",
'incrNoSymptom': "新增无症状","newConfirm": "确诊2","newDead":"死亡2","newHeal": "治愈2"}
# 将英文关键字转换为中文
today_real = {} #保存当天数据的字典
for key in china_real_data['today'].keys():
today_real["当天"+cn_en_dic[key]] = china_real_data['today'][key]
total_real = {} #保存总计数据的字典
for key in china_real_data['total'].keys():
total_real["总计"+cn_en_dic[key]] = china_real_data['total'][key]
extData_real = {} #保存其它数据的字典
if type(china_real_data['extData']) == type(dict()):
for key in china_real_data['extData'].keys():
extData_real[cn_en_dic[key]] = china_real_data['extData'][key]
extData_real["名称"] = china_real_data['name'] #提取省份或国家名
extData_real["编号"] = china_real_data['id'] #提取省份或国家的编号
else:
extData_real["名称"] = "中国"
extData_real['时间'] = china_real_data['date']
#将today,total和其它值,通过concat命令合并成一条记录
real_df = pd.DataFrame([today_real]) #将当天数据转换为df
real_df1 = pd.DataFrame([total_real]) #将总计数据转换为df
real_df2 = pd.DataFrame([extData_real]) #将其它数据转换为df
#将上面的三个df合并成1个df
china_real_df = pd.concat([real_df2,real_df,real_df1],axis=1) #concat时将多个df数据合并成1个df
return china_real_df
# 功能函数2:将数据保存到本地
def save_def(china_real_df,name):
china_real_df.to_csv(name) #保存为csv
# china_real_df.to_excel("china_real_data.xlsx") #保存为excel
#主函数:
def main():
#要请求的url
url = "https://c.m.163.com/ug/api/wuhan/app/data/list-total?t=319439847098"
html = url_def(url) #请求网页数据函数
data_v1 = data_def(html) #获取data数据函数
# return data_v1
print("请选择您要获取的数据编号:\n1.中国实时数据\n2.全球实时数据\n3.中国历史数据\n4.全球每个国家的实时数据\n")
sel_v1 = input("请输入您的选择")
if sel_v1 == "1":
pass
# 1.中国实时数据
# china_real_data = china_real_def(data_v1) #获取中国实时数据函数
# chian_real_df = change_def(area_real_data)
elif sel_v1 == "2":
#2.全球实时数据
area_df = pd.DataFrame() #建立空的df
for i in range(len(data_v1['areaTree'])):
#使用的函数4
area_real_data = area_real_def(data_v1,i) #获取全球实时数据
area_real_df = change_def(area_real_data) #使用功能函数转换列标题
area_df = pd.concat([area_df,area_real_df])
area_df = area_df.reset_index(drop=True) #给表创建新的索引,drop的作用:删除原来的索引列
save_def(area_df,"area_real_data.csv") #保存数据到本地
return area_df
elif sel_v1 == "3":
#3.中国历史数据
hist_df = pd.DataFrame() #建立空的df
for i in range(len(data_v1['chinaDayList'])):
#使用函数5
china_hist_data = china_hist_def(data_v1,i) #获取全球实时数据
china_hist_df = change_def(china_hist_data) #使用功能函数转换列标题
hist_df = pd.concat([hist_df,china_hist_df])
hist_df = hist_df.reset_index(drop=True) #给表创建新的索引,drop的作用:删除原来的索引列
save_def(hist_df,'china_hist_data.csv') #保存数据到本地
return hist_df
elif sel_v1 == "4":
name_list = [] #存放那些国家有省份数据的国家名
num_list = [] #存放国家的编号
#提取国家名和编号
for i in range(len(data_v1['areaTree'])):
if data_v1['areaTree'][i]['children']:
name_list.append(data_v1['areaTree'][i]['name'])
num_list.append(i)
#在input中,输出国家名的提示窗口
name_v2 = "|".join([str(name_list.index(name)+1)+"."+name for name in name_list])
sel_v2 = input("请输入您的选择{}".format(name_v2))
#4.全球每个国家各省份的实时数据
area_df = pd.DataFrame() #建立空的df
try:
for j in range(len(data_v1['areaTree'][num_list[int(sel_v2)-1]]['children'])):
#使用的函数6
area_real_data = country_real_def(data_v1,num_list[int(sel_v2)-1],j) #获取全球每个国家各省的实时数据
area_real_df = change_def(area_real_data) #使用功能函数转换列标题
area_df = pd.concat([area_df,area_real_df])
area_df = area_df.reset_index(drop=True) #给表创建新的索引,drop的作用:删除原来的索引列
save_def(area_df,"{}_country_real_data.csv".format(name_list[int(sel_v2)-1])) #保存数据到本地
return area_df
except IndexError:
print("您的输入有误!应该输入(1-7)的数字")
elif sel_v1 == "5":
#扩展功能(全球各国的历史数据)
#找到各国的编号
url = "https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode={}".format("66")
print("全球各国的历史数据")
pass
elif sel_v1 == "6":
#扩展功能(中国各省的历史数据)
#找到各省份的编号
url = "https://c.m.163.com/ug/api/wuhan/app/data/list-by-area-code?areaCode={}".format("420000")
print("中国各省的历史数据")
pass
else:
print("您的输入有误")
#函数入口
if __name__ == "__main__":
#忽略警告
import warnings
warnings.simplefilter('ignore')
hist_df = main()
hist_df