一、某日期以来的世界各国疫情数据爬取
1 思路
把功能封装到一个类中
每一个小功能变成一个方法
1.1 定义一个类
class CoronaVirusSpider(object):
让定义类从首页开始工作
利用self方法指定被访问的页面,init使初始化时就把页面准备好
def __init__(self):
self.home_url = 'https://ncov.dxy.cn/ncovh5/view/pneumonia'
封装一个发送请求的方法,提高代码复用性
def get_content_from_url(self, url):
"""
根据URL获取响应内容
:param url: 请求的URL
:return: URL的响应的内容字符串
"""
response = requests.get(url)
return response.content.decode()
再定义一个方法,从首页提取并解析数据
def parse_home_page(self, home_page):
保存数据,定义保存数据的内容(data)和路径(path)
def save(self, data, path):
with open(path, 'w') as fp:
json.dump(data, fp, ensure_ascii=False)
采集过程
def crawl_last_day_corona_virus(self):
# 1. 获取首页内容
home_page = self.get_content_from_url(self.home_url)
# 2. 解析数据
last_day_corona_virus = self.parse_home_page(home_page)
# 3. 保存数据
self.save(last_day_corona_virus, 'data/last_day_corona_virus.json')
加载各国疫情数据
with open('data/last_day_corona_virus.json') as fp:
last_day_corona_virus = json.load(fp)
定义列表, 用于存储各国从1月23日以来疫情数据
corona_virus = []
遍历各国疫情数据, 获取统计的URL
for country in tqdm(last_day_corona_virus, '采集1月23日以来各国疫情信息'):
发送请求, 获取各国从1月23号至今的json数据
statistics_data_url = country['statisticsData']
statistics_data_json_str = self.get_content_from_url(statistics_data_url)
把json数据转换为Python类型的数据, 添加列表中
statistics_data = json.loads(statistics_data_json_str)['data']
for one_day in statistics_data:
one_day['provinceName'] = country['provinceName']
one_day['countryShortCode'] = country['countryShortCode']
corona_virus.extend(statistics_data)
把列表以json格式保存为文件
self.save(corona_virus, 'data/corona_virus.json')
提供一个run方法,运行程序
def run(self):
self.crawl_last_day_corona_virus()
self.crawl_corona_virus()
if __name__ == '__main__':
spider = CoronaVirusSpider()
spider.run()
期间遇到了一个错误,提示UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\xe7‘ in position 295: illegal multibyte seq
这是在将uft-8的编码写入文档,并输出的时候,出现这了这个报错,说gbk无法编码
解决的办法是在with语句里定义一个encoding为utf-8
顺便记忆一下相关知识:
1.str转bytes叫encode,bytes转str叫decode
2.字符就是unicode字符,字符串就是unicode字符数组
open()函数的默认编码不是utf-8,修改编码方式即可
函数中的参数必须是str,不能是bytes,也就是说json.dump(result)中的result参数如果是bytes需要先decode成str(比如result.decode(‘utf-8’)),才能使用open()函数的encoding
运行一下:
上面的进度条可以显示代码执行进度,是由tqdm实现的,具体方法是在代码开头:
from tqdm import tqdm
并且在遍历时定义方法
for country in tqdm(last_day_corona_virus, '采集1月23日以来各国疫情信息'):
成功了