这里写自定义目录标题
Python爬取疫情实战
项目环境
环境:python 3.7
工具:pycharm
爬取疫情数据
用到的包
import requests, time, json
from datetime import datetime
爬取使用的网站
url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_other'
# 中国疫情总信息网站
url2 = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
# 中国各省市的详细信息网站
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
} # 请求头
获取中国疫情总信息
def run(url, header):
"""获取中国疫情总数据"""
# 爬取网站
r = requests.get(url, headers=header)
r.encoding = r.apparent_encoding
# 改变text格式
dic = json.loads(r.text)
# 获取data中的内容
data_all = json.loads(dic['data'])
# 获取历史
history = {
} # 以字典形式存储
for i in data_all['chinaDayList']:
date = '2020.'+i['date'] # 获取日期
new_date = datetime.strptime(date, '%Y.%m.%d') # 转换成datetime
date = new_date.strftime('%Y-%m-%d') # 转换成str
confirm = i['confirm'] # 确诊人数
suspect = i['suspect'] # 疑似人数
heal = i['heal'] # 治愈人数
dead = i['dead'] # 死亡人数
history[date] = {
'confirm': confirm,
'suspect': suspect,
'heal': heal,
'dead': dead
}
for j in data_all['chinaDayAddList']:
date = '2020.'+j['date'] # 获取日期
new_date = datetime.strptime(date, '%Y.%m.%d')
date = new_date.strftime('%Y-%m-%d')
confirm_add = j['confirm'] # 新增确诊人数
suspect_add = j['suspect'] # 新增疑似人数
heal_add = j['heal'] # 新增治愈人数
dead_add = j['dead'] # 新增死亡人数
history[date].update({
'confirm_add': confirm_add, 'suspect_add': suspect_add, 'heal_add': heal_add, 'dead_add': dead_add})
return history
获取中国各省市的详细信息
def detail(detail_url, header):
"""获取各个省市的详细信息"""
r = requests.get(detail_url)
r.encoding = r.apparent_encoding
dic = json.loads(r.text)
data_all = json.loads(dic['data'])
d = data_all['areaTree'] # 获取地区
date = data_all['lastUpdateTime'] # 获取日期
details = [] # 以列表形式存储
for i in d[0]['children']:
# d[0]表示中国,中国各个省份信息存储在d[0]['children']中,获取中国各省信息
province_name = i['name'] # 省名
for j in i['children']: # 市的详细信息
city_name = j['name'] # 市名
confirm = j['total']['confirm']
heal = j['total']['heal']
dead = j['total']['dead']
new_confirm = j['today']['confirm']
details.append([date, province_name, city_name, confirm, new_confirm, heal, dead])
return details
向数据库中插入、更新数据
创建数据库
创建数据库,包含两个表details,history
CREATE TABLE `details` (
`id` int NOT NULL AUTO_INCREMENT,
`update_time` datetime DEFAULT NULL COMMENT '数据最后更新时间',
`province` varchar(50) DEFAULT NULL COMMENT '省',
`city` varchar(50) DEFAULT NULL COMMENT '市',
`confirm` int DEFAULT NULL COMMENT '累计确诊',
`confirm_add` int DEFAULT NULL COMMENT '新增确诊',
`heal` int DEFAULT NULL COMMENT '累计治愈',
`dead` int DEFAULT NULL COMMENT '累计死亡',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=923 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
CREATE TABLE `history` (
`ds` datetime NOT NULL COMMENT '日期',
`confirm` int DEFAULT NULL COMMENT '累计确诊',
`confirm_add` int DEFAULT NULL COMMENT '当日新增确诊',
`suspect` int DEFAULT NULL COMMENT '剩余疑似',
`suspect_add` int DEFAULT NULL COMMENT '当日新增疑似',
`heal` int DEFAULT NULL COMMENT '累计治愈',
`heal_add` int DEFAULT NULL COMMENT '当日新增治愈',
`dead` int DEFAULT NULL COMMENT '累计死亡',
`dead_add` int DEFAULT NULL COMMENT '当日新增死亡',
PRIMARY KEY (`ds`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
用到的包
import time, pymysql, traceback
编写连接、断开连接数据库函数
def get_conn():
"""创建连接"""
# 建立连接
# user为数据库用户,password是数据库密码,db为已建的数据库名字
conn = pymysql.connect(user='#', password='#', db='#')
# 创建游标,元组类型
cursor = conn.cursor()
return conn, cursor
def close_conn(conn, cursor):
"""关闭连接"""
if cursor:
cursor.close()
if conn:
conn.close()
插入以及更新各省市详细信息
def update_details():
# 插入、更新详细信息
cursor = None
conn = None
try:
d = detail(url2, header)
conn, cursor = get_conn() # 开始连接
sql = "insert into details(update_time,province,city,confirm,confirm_add,heal,dead) values(%s,%s,%s,%s,%s,%s,%s)"
sql_query = 'select %s=(select update_time from details order by id desc limit 1)'
cursor.execute(sql_query, d[0][0]) # 数据库日期与最新日期的比较
if not cursor.fetchone()[0]: # 若数据库日期不是最新日期,则更新数据库
print(f"{time.asctime()}开始更新最新数据")
for i in d:
cursor.execute(sql, i) # 向数据库插入数据
conn.commit() # 提交事务
print(f"{time.asctime()}更新最新数据完毕")
else:
print(f"{time.asctime()}已是最新数据")
except:
traceback.print_exc() # 以日志形式打印错误
finally:
close_conn(conn, cursor) # 关闭连接
插入、更新中国疫情总信息
def insert_history(): # 插入历史数据
cursor = None
conn = None
try:
h = run(url, header)
print(f"{time.asctime()}开始插入历史数据")
conn, cursor = get_conn()
sql = "insert into history values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"