前言
有时候,我们想多打几场比赛,却苦于没有提前在每个平台上找而错过,明明关注了邮件,却因为邮件的提醒时间太短而来不及安排。
今天,这个问题彻底被解决了!
大家应该都知道windows的日历,里面的日程功能用的人不多,但是它真的非常好用。
我写了一个小程序,自动抓取更新每天的比赛并转化为订阅格式。
首先放上地址,如果想听原理可以往后看。
安装方法
outlook网页版
- 点击日历视图
- 点击添加日历 - 从web订阅
- 粘贴链接
outlook
- 点击日历视图
- 右键任意一个日历组(如我的日历)
- 点击添加日历 - 从internet
- 输入刚刚的地址
- 进行最后的配置,完成
windows 日历应用
我强烈推荐你使用outlook或它的网页版,因为这个日历的同步有些问题,我也在添加日历那里转了很久进不去。
IOS 日历
- 点击添加日历 - 添加订阅日历
- 粘贴链接
- 进行自定义设置,完成
其他日历软件
有两种方法,一是在outlook网页版直接用微软账户登录添加日历,然后在日历应用里添加这个账户。
或者这个应用直接支持订阅,就可以直接粘贴链接进去。
无论如何,我强烈推荐在所有地方使用一个日历账户,这样的话创建的日程可以同步。
原理
本质上来说,这个订阅链接背后就是一个文件,我只需要用现有的库和爬虫就可以处理。
- ics文件 - ics库
- 解析html - BeautifulSoup4
- 爬虫 - requests
比如说这是洛谷的获取脚本:
import requests
import re
from bs4 import BeautifulSoup
import datetime
import urllib
import json
headers = {
'UserAgent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE'
}
def getcontest():
res = requests.get('https://www.luogu.com.cn/contest/list', headers=headers)
mat = re.findall(r'JSON\.parse\(decodeURIComponent\("(\S+)"\)',res.text)[0]
mat = json.loads(urllib.request.unquote(mat))
rt = []
for t in mat['currentData']['contests']['result']:
title = t['name']
startTime = datetime.datetime.fromtimestamp(t['startTime'])
endTime = datetime.datetime.fromtimestamp(t['endTime'])
startTime = startTime + datetime.timedelta(hours=-8)
endTime = endTime + datetime.timedelta(hours=-8)
rt.append({
"title":title,
"start":startTime,
"end":endTime
})
return rt
if __name__ == '__main__':
for res in getcontest():
# change UTC time to local time(UTC+8)
res["start"] = res["start"].replace(tzinfo=datetime.timezone(datetime.timedelta(hours=8)))
res["end"] = res["end"].replace(tzinfo=datetime.timezone(datetime.timedelta(hours=8)))
print(res['title'],res['start'],res['end'])
然后最后需要一个主程序把这些脚本一起调用生成日历:
import luogu
import atcoder
import codeforces
import ics
import upload
import requests
class tmpfile:
def __init__(self,data):
self.data = data
def read(self,a):
print(a)
return self.data
def main_func(a='a',b='b'):
try:
registered = [
luogu.getcontest(),
atcoder.getcontest(),
codeforces.getcontest()
]
calendar = ics.Calendar()
for dat in registered:
if dat!=None:
for res in dat:
print(res['title'],'|', res['start'],'|', res['end'])
e = ics.Event()
e.name = res['title']
e.begin = res['start']
e.end = res['end']
calendar.events.add(e)
upd = tmpfile(data=calendar.serialize())
upload.upload(upd)
# open('a.ics','w',encoding='utf-8').write(upd.read(0))
if __name__ == '__main__':
main_func()
最后再把这些文件和依赖打包上传到腾讯云的scf云函数,设置定期执行就好了。
结尾
科技极大地方便了我们的生活,它的门槛也在逐步降低,相信未来的世界会因为科技变得更好!