发布时间:2022-08-31 11:30
在线地图
我校传统是五一放七天,五一前两天开始放,当时疫情初见端倪,但是网上并没有找到准确显示病例位置的地图
后来知道腾讯地图是有的,但是不支持选择时间区间,所以把很早之前的也都显示了出来,整个地图很乱,几乎没有实际价值
所以出去玩前花了2个小时做了个简易版的地图,然后就快快乐乐和人出去了。最近又加上了爬虫,自动上传服务器,高德API并发,觉得可以把这个大杂烩发出来了
需要说在前面的是,适度爬虫,不要给服务器造成压力,比如做好本地存储避免重复访问,限制爬虫频率等,我这里限制了至少间隔 1s 才能访问一次
爬虫都是就题发挥,这里提取所有 a标签
,然后筛选出 title
包含“日”、“月”、“新增”、“例”的。值得注意的是,北京卫健委有很简单的反爬虫机制,你需要把 User-Agent 伪装一下
def update(url='http://wjw.beijing.gov.cn/xwzx_20031/wnxw/'):
'''北京卫健委爬虫'''
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36"}
bs = BeautifulSoup(
kind_get(url, headers=headers).text, 'lxml')
for news in bs.find_all('a'):
try:
title = news['title']
except KeyError:
pass
else:
if title.find('月') != -1 and title.find('日') != -1 and title.find('例') != -1:
print(title)
然后把月和日用正则表达式提取出来,再访问 href
,进一步把所有含有"现住"的 p标签
提取出来
date = re.search('(?<=北京).*?(?=新增)', title)
if date:
m, d, _ = re.split("[月日]", date.group())
path = './data/{}{}.txt'.format(m.zfill(2), d.zfill(2))
if not os.path.exists(path):
bs_news = BeautifulSoup(
kind_get(parse.urljoin(url, news['href']), headers=headers).text, 'lxml')
try:
with open(path, 'w', encoding='utf-8') as file:
article = bs_news.find('div', class_='view')
for item in article.find_all('p'):
if item.text.find('现住') != -1:
file.write(item.text+'\n')
print(date.group(), '数据文件添加成功')
except AttributeError:
print(article)
print(date.group(), '数据文件添加异常,可能当日病例没有明确地址')
os.remove(path)
else:
print(date.group(), '数据文件已存在')
提取出来的数据大概长这样
确诊病例1、3、4、19:现住朝阳区劲松街道农光里。5月6日诊断为确诊病例,临床分型均为轻型。
确诊病例2:现住朝阳区高碑店西店社区义安门兰花巷。5月6日诊断为确诊病例,临床分型为轻型。
确诊病例5、6、7:现住海淀区甘家口街道甘东社区。5月6日诊断为确诊病例,临床分型均为轻型。
确诊病例8:现住海淀区甘家口街道增光佳苑。5月6日诊断为确诊病例,临床分型为轻型。
确诊病例9:现住海淀区西北旺镇大牛坊社区。5月6日诊断为确诊病例,临床分型为轻型。
接下来就是拆分出每个病例的住址了,这里最普遍的格式是 确诊病例x,现住xxxxx。,但是还有很多奇奇怪怪的格式
确诊病例123,现住xxxxx。
用正则表达式提取“现住”和“。”的中间
确诊病例1、45、47至48,现住xxxx。
这里病例数不是 1,先用正则匹配出“病例”和“,”中间,然后先按“、"分隔一次,再用至分隔一次,然后一个个加起来
确诊病例3,现住址和1相同。
与其倒回去找1,不如在病例 1 的时候用正则表达式提取整个文章出现几次 1。这里提取 1 有一点点难度,因为要排除 12 这种,我编写的正则表达式是 f"(?<=[^0-9]){int(ID)}(?=[^0-9])"
,ID是对应病例编号,这个表达式的意义是找 ID 且左右两边不是数字。