使用python获取日历信息并制作订阅文件 您所在的位置:网站首页 苹果节日日历订阅 使用python获取日历信息并制作订阅文件

使用python获取日历信息并制作订阅文件

2023-08-09 17:42| 来源: 网络整理| 查看: 265

使用python获取日历信息并制作订阅文件 前言准备工作节日信息抓取日历订阅文件设置订阅日历信息总结

前言

最近使用日历应用程序,但发现在日历上诸多节日没有显示,先不说假日调休一事,这个是国内一大特色,它也不好预料,可是比较常见的节日都没有自带显示,写这篇文章时恰巧临近母亲节,打开日历一看,找不到,百度搜索看看。

非常紧跟时事,在推荐下拉框就有关于节日不显示的问题,在之前我也不知道如何导入订阅日历,先点一个订阅地址的链接进去,发现有教程教如何设置日历,我也顺利导入成功了,但是只有节假日放假与调休的,不满足我想要的,其他链接下均没有找到相关教程。

准备工作

思考良久,解决灵感就想到了既然别人能设置成订阅日历,为啥我自己不做一个呢。开始回找那个链接地址处于何处,没想到制作者把他开源在github上,在国内搭建了服务器,这样国内用户使用ics(苹果日历订阅文件)链接就不会提示无法验证的消息导致不能完成日历订阅。

方案来源:如下

可以看到起作用的是这个ics文件,即弄明白这个文件格式就可以复写出一模一样的ics文件出来。文件结构如下:

先声明日历名称及日历对应的时区,之后的事件构建基本都是重复同一个模板填充,不同点为开始始日,结束日,及其名称描述。

弄明白这个也就很好往下进行了,日历制作,单靠自己翻找各个节日也不方便,既然已经想程序化那就多设置几个节日,经过一段时间的网上冲浪,发现日历网站收录的节日信息较多,且能满足当前需求,点击日历网,再点击节日大全。

节日信息抓取

下面编写程序抓取日历信息,并将其转换为ics文件。

首先试探下网页能不能比较友好的获取,获取还算是简单,只需要正常传入请求头即可。

再分析网页结构,由于是静态网页,直接抓取element信息就行,其关键信息在li节点下,这里使用xpath进行解析,//li[@class="jr1"]//text(),即可完成节点文本数据获取。

结果形如:元旦[1月1日],其中在ics文件中日期应当为年月日的结构,再引入datetime模块对日期进行解析后转换为年月日结构:20220101。

抓取网页信息代码如下:

from datetime import datetime import re import httpx # httpx与requests的api相似,可以仅更改httpx为requests,代码运行无误 from faker import Faker # 设置伪造请求头user-agent from lxml import etree def get_url(): headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'User-Agent': Faker().chrome(version_from=98, version_to=100, build_from=4800, build_to=5000), 'Host': '日历网站', 'Referer': '日历网站', } url = '日历网站' try: response = httpx.get(url, headers=headers) if response.status_code == 200: return response.text else: return None except Exception as e: print(e) return None def parse_jr_date(text, y): jr, dt = text.split('[') dt = f'{y}年' + re.search(r'\d{1,2}月\d{1,2}日', dt).group() dt = datetime.strptime(dt, '%Y年%m月%d日').strftime('%Y%m%d') return jr, dt def parse_html(html): html = etree.HTML(html) date = html.xpath('//meta[@name="LastUpdate"]/@content')[0] y = datetime.strptime(date, '%Y/%m/%d %H:%M:%S').year jr_rili = ''.join(html.xpath('//li[@class="jr1"]//text()')).split(']')[:-1] return y, jr_rili 日历订阅文件设置

根据前文分析ics文件的设置框架,可以简单将ics文件拆分成ics头部设置和ics事件设置:

from datetime import datetime now = datetime.now().strftime('%Y%m%dT%H:%M:%S') def set_ics_header(year): # year为当前年份 return "BEGIN:VCALENDAR\n" \ + "PRODID:NULL\n" \ + "VERSION:2.0\n" \ + "CALSCALE:GREGORIAN\n" \ + "METHOD:PUBLISH\n" \ + f"X-WR-CALNAME:{year}年节假日\n" \ + "X-WR-TIMEZONE:Asia/Shanghai\n" \ + f"X-WR-CALDESC:{year}年节假日\n" \ + "BEGIN:VTIMEZONE\n" \ + "TZID:Asia/Shanghai\n" \ + "X-LIC-LOCATION:Asia/Shanghai\n" \ + "BEGIN:STANDARD\n" \ + "TZOFFSETFROM:+0800\n" \ + "TZOFFSETTO:+0800\n" \ + "TZNAME:CST\n" \ + "DTSTART:19700101T000000\n" \ + "END:STANDARD\n" \ + "END:VTIMEZONE\n" def set_jr_ics(jr, date, uid): # jr: 节日,date:日期,uid:编序 return "BEGIN:VEVENT\n" \ + f"DTSTART;VALUE=DATE:{date}\n" \ + f"DTEND;VALUE=DATE:{date}\n" \ + f"DTSTAMP:{date}T000001\n" \ + f"UID:{date}T{uid:0>6}_jr\n" \ + f"CREATED:{date}T000001\n" \ + f"DESCRIPTION:{jr}\n" \ + f"LAST-MODIFIED:{now}\n" \ + "SEQUENCE:0\n" \ + "STATUS:CONFIRMED\n" \ + f"SUMMARY:{jr}\n" \ + "TRANSP:TRANSPARENT\n" \ + "END:VEVENT\n"

将获取到的日期信息应用到上面代码中:

def concat_ics(y, jr): # 返回一个完整的ics文件内容 header = set_ics_header(y) jr_rq = list(map(parse_jr_date, jr, [y] * len(jr))) # 将同一天的节日进行编号 jr_rq.sort(key=lambda x: x[1]) pre_num = 0 for num in range(len(jr_rq)): if jr_rq[num][1] != jr_rq[pre_num][1]: pre_num = num jr_rq[num] += (num - pre_num + 1,) jr_ics = ''.join(map(lambda x: set_jr_ics(*x), jr_rq)) return header + jr_ics + 'END:VCALENDAR'

保存为ics文件:

def save_ics(fname, text): with open(fname, 'w', encoding='utf-8') as f: f.write(text) # fname: calendar_{year}_jr.ics

以上就是从日历网获取日历信息到制作ics文件的全过程,代码已开源:

github地址:【https: //github.com/lk-itween/Calendar 】

订阅日历信息

上述操作弄完后并不能在手机上看到设置好的日历信息,这时把制作的ics文件放到可以可访问的网上,再通过苹果的日历订阅就可以使用了,或许可以将文件保存到手机里面,通过文件路径的方式访问ics文件,接下来只讨论将其放到网上。

不用搭建服务器,使用代码托管平台,如github,但是这个国内访问较为吃力,那么可以试试gitee,同样也是代码托管平台,或许还有其他的,只要能通过公域网访问,且能保存ics文件的网站即可。

在github或者gitee里面新建一个仓库。

github:

gitee(如果是gitee托管代码仓库,需要在管理页面将仓库设置为公开):

设置好仓库名,将ics文件上传即可,以gitee为例,上传完后等待页面刷新,会出现你上传的几个文件,如calendar_2022_jr.ics:

此时点击需要订阅的日历文件,如calendar_2022_jr.ics,再点击原始数据:

复制网址,或者复制上面页面对应的网址,将blob修改为raw:

接下来,打开手机,进入日历,点击日历界面的下方日历:

再点击添加日历 -> 添加订阅日历:

在输入框输入刚才复制的网址,比如我的为:(https://gitee.com/kangliz/Calendar/raw/main/calendar_2022_jr.ics

再点击订阅,如果没有检测出网页异常,就会显示以下页面:

可以修改标记颜色,然后点击添加即日历订阅成功。

总结

本篇简单的介绍了如何从网站获取日历信息并将其制作成ics文件,供ios系统的日历应用程序订阅日历,可根据此篇内容动手制作一个日历订阅文件,并将其上传至可使用网站上。

日有所思夜有所梦,前方的道路无论是否顺畅都应当坚持往前走。

于二零二二年五月七日作



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有