上一章:
python 爬虫爬取疫情数据,爬虫思路和技术你全都有哈(一、爬虫思路及代码)
清洗数据很简单,就是数据太乱的话,就得花些时间,所以一定要有一个好的方法,才能避免在清洗数据上花费太多的时间
def xpath_json(resp):
print('xpath_json ------ 2')
html = etree.HTML(resp)
str_list = html.xpath("//script[@id='captain-config']/text()")
str_list = str_list[0].replace('\'', '') # 去掉 '' 单引发
str_list = str_list.encode('utf-8') # 转码字符集,转码中文
# str_list = str_list.encode('utf-8').decode('unicode_escape') # 转码字符集,转码中文
json_list = json.loads(str_list)
return json_list
if __name__ == '__main__':
url = 'https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner&city='
# 请求HTTP
resp = HTTP_get(url)
print(resp)
# 解析数据
json_list = xpath_json(resp)
# 加上这样一个代码,之后会去掉的,只是方便 我们清洗数据,看清这个json格式
with open('JsonData.json','w+',encoding='utf-8') as f:
f.write(str(json_list))
运行后,按下 ctrl + alt + L 进行数据格式化,之后就是这样了哈,50000多条,有点多哈
慢慢分析这些数据
验证一下是不是这些的数据,去百度查询西藏的总数据。
结果数据都是正确的,那么我们成功找到了我们想要的数据了。
英文的大概意思就是这些。
confirmedRelative # 新增确诊 unOverseasInputNewAdd # 新增本土 overseasInputRelative # 新增境外 asymptomaticRelative # 新增无症状 curConfirm # 现有确症 ------ curLocalConfirm # 现有本土 curOverseasInput # 现有境外 asymptomatic # 现有无症状 confirmed # 累计确诊 ------ overseasInput # 累计境外 cured # 累计治愈 ------ died # 累计死亡 ------ noNativeRelativeDays # 连续有无新增
接下来就是把我们所需要的数据给清洗出来,
省 :现有确症、 累计确诊、 累计治愈、 累计死亡
市:现有确症、 累计确诊、 累计治愈、 累计死亡
然后就是存入数据库了,mysql哦,记得要先创建数据库和表
数据库字段 以及字段类型
数据库代码如下(这部分代码一定要在爬虫代码的前面,不然会报没有定义这样的变量的错误):
import pymysql
# 连接数据库
conn = pymysql.connect(
host='127.0.0.1',
user='root',
password='你数据库的PW',
database='数据库名字',
charset='utf8'
)
# 获取光标
cursor = conn.cursor()
爬虫代码如下:
def xpath_json(resp):
print('xpath_json ------ 2')
html = etree.HTML(resp)
str_list = html.xpath("//script[@id='captain-config']/text()")
str_list = str_list[0].replace('\'', '') # 去掉 '' 单引发
str_list = str_list.encode('utf-8') # 转码字符集,转码中文
# str_list = str_list.encode('utf-8').decode('unicode_escape') # 转码字符集,转码中文
json_list = json.loads(str_list)
return json_list
# 数据清洗
def domesticData(json_list):
domestic = json_list['component'][0]['caseList'] # 国内疫情情况
# 省循环
for province in domestic:
temp_province = []
# temp_province.append(province['confirmedRelative']) # 新增确诊
# temp_province.append(province['nativeRelative']) # 新增本土
# temp_province.append(province['overseasInputRelative']) # 新增境外
# temp_province.append(province['asymptomaticRelative']) # 新增无症状
temp_province.append(province['curConfirm']) # 现有确症
temp_province.append(province['confirmed']) # 累计确诊
temp_province.append(province['crued']) # 累计治愈
temp_province.append(province['died']) # 累计死亡
# 给空数据赋默认值
if temp_province[0] == "":
temp_province[0] = 0
if temp_province[1] == "":
temp_province[1] = 0
if temp_province[2] == "":
temp_province[2] = 0
if temp_province[3] == "":
temp_province[3] = 0
if temp_province[4] == "":
temp_province[4] = 0
print("省:" + province["area"])
print('现有确症:' + province['curConfirm'])
print('累计确诊:' + province['confirmed'])
print('累计治愈:' + province['crued'])
print('累计死亡:' + province['died'])
# 编写 存入省的数据 sql脚本
sql = 'insert epidemicSituation(CityName,nativeRelative,curConfirm,confirmed,crued,died,AddDatetime) ' \
f'values("{province["area"]}",{temp_province[0]},{temp_province[1]},{temp_province[2]},{temp_province[3]},{temp_province[4]},"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}")'
# 执行sql
cursor.execute(sql)
# 提交
# conn.commit()
# 市循环
for city in province['subList']:
# 去除掉一些不需要的杂乱数据
if city['city'] == '境外输入':
continue
elif city['city'] == '待确认':
continue
elif city['city'].find('外') != -1 and city['city'].find('来') != -1:
continue
elif city['city'] == '涉冬(残)奥闭环人员':
continue
temp_city = []
# temp_city.append(city['nativeRelative']) # 新增本土
# temp_city.append(city['asymptomaticRelative']) #新增无症状
# temp_city.append(city['confirmedRelative']) # 新增确诊
temp_city.append(city['curConfirm']) # 现有确症
temp_city.append(city['confirmed']) # 累计确诊
temp_city.append(city['crued']) # 累计治愈
temp_city.append(city['died']) # 累计死亡
# temp_city.append(province['noNativeRelativeDays']) #连续有无新增
# temp_city.append(city['overseasInputRelative']) #新增境外
# 判断不能为空
if temp_city[0] == "":
temp_city[0] = 0
if temp_city[1] == "":
temp_city[1] = 0
if temp_city[2] == "":
temp_city[2] = 0
if temp_city[3] == "":
temp_city[3] = 0
if temp_city[4] == "":
temp_city[4] = 0
print("城市:"+city["city"])
print('现有确症:'+city['nativeRelative'])
print('累计确诊:'+city['curConfirm'])
print('累计治愈:'+city['confirmed'])
print('累计死亡:'+city['crued'])
# 编写 市的数据sql语句
sql = 'insert epidemicSituation(CityName,nativeRelative,curConfirm,confirmed,crued,died,AddDatetime) ' \
f'values("{city["city"]}",{temp_city[0]},{temp_city[1]},{temp_city[2]},{temp_city[3]},{temp_city[4]},"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}")'
cursor.execute(sql)
# conn.commit()
break
break
if __name__ == '__main__':
url = 'https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner&city='
# 请求HTTP
resp = HTTP_get(url)
print(resp)
# 解析数据
json_list = xpath_json(resp)
""" 这个代码就可以删掉了,毕竟他只是让我们更好的解析数据和清洗数据
# 加上这样一个代码,之后会去掉的,只是方便 我们清洗数据,看清这个json格式
with open('JsonData.json','w+',encoding='utf-8') as f:
f.write(str(json_list))
"""
# 清洗数据
domesticData(json_list)
上面代码中,我把 conn.commit() 注释掉了,想要数据如果就得先打开,并且在for循环最后见加了两个 break 所以数据只有一个省的数据和市的数据
运行结果 如下(前面的代码之所以没写运行结果,是应为太多了,给不出来):
对比一下
数据入库,也正常
全国疫情数据,他的格式和其他省市的数据有点区别,所以就单独给提出来写了一个函数,因为只有一条数据,所以还是很简单的
def domesticSumDataMain(json_list):
print('domesticSumDataMain ------ 8')
# print(json_list['component'][0]['summaryDataIn'])
sum = json_list['component'][0]['summaryDataIn']
Sum_domestic = []
# Sum_domestic.append(sum['confirmedRelative']) # 新增确诊
Sum_domestic.append(sum['unOverseasInputNewAdd']) # 新增本土
# Sum_domestic.append(sum['overseasInputRelative']) # 新增境外
# Sum_domestic.append(sum['asymptomaticRelative']) # 新增无症状
Sum_domestic.append(sum['curConfirm']) # 现有确症 ------
# Sum_domestic.append(sum['curLocalConfirm']) # 现有本土
# Sum_domestic.append(sum['curOverseasInput']) # 现有境外
# Sum_domestic.append(sum['asymptomatic']) # 现有无症状
Sum_domestic.append(sum['confirmed']) # 累计确诊 ------
# Sum_domestic.append(sum['overseasInput']) # 累计境外
Sum_domestic.append(sum['cured']) # 累计治愈 ------
Sum_domestic.append(sum['died']) # 累计死亡 ------
# Sum_domestic.append(sum['noNativeRelativeDays']) # 连续有无新增
print('全国疫情数据')
print('新增本土:'+sum['unOverseasInputNewAdd'])
print('现有确症:'+sum['curConfirm'])
print('累计确诊:'+sum['confirmed'])
print('累计治愈:'+sum['cured'])
print('累计死亡:'+sum['died'])
sql = 'insert epidemicSituation(CityName,nativeRelative,curConfirm,confirmed,crued,died,AddDatetime) ' \
f'values("全国",{Sum_domestic[0]},{Sum_domestic[1]},{Sum_domestic[2]},{Sum_domestic[3]},{Sum_domestic[4]},"{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}")'
cursor.execute(sql)
# conn.commit()
return Sum_domestic
if __name__ == "__main__"
a = domesticSumDataMain(json_list) # 全国的疫情人数
print(a)
存入数据库的话记得 打开 conn.commit() 的注释
结果如下:
对比百度API结果
完全正确,没问题
而且数据库里也有记录,完美完成。
上一章:
python 爬虫爬取疫情数据,爬虫思路和技术你全都有哈(一、爬虫思路及代码)
下一章:利用爬取的疫情数据制作全国疫情地图