本文原理性说明略多,如不想看,那么下面的一键直达,应该适合你
前言
《小爱课程表》是小米最新推出的课程表应用。
所有使用MIUI12
的小米手机都自带,它具有课程提醒和上课静音的功能,并且支持负一屏展示、日历订阅等非常实用的功能。
当然,其他手机也能用,小爱课程表应用目前已经上架了多个应用商店,包括iOS 和安卓商店
,所以,只需要去应用商店搜索「小爱课程表」下载即可食用,它相比其他课程表产品的优势在于:更新及时,界面简洁无广告,设置课程便捷,可添加桌面小部件(所以负一屏展示这个功能,可能就MIUI12支持了吧,安利一下)。
下面放一些效果图:
另外,值得一提的是,小爱课程表推出了和小爱同学一起打造最好用的课程表的内测功能,号称:只需一点JS基础,几十行代码,便可参与课程表项目,体会代码落地产品的乐趣,用你的高超技艺造福同校同学!
,如果你有适配的想法,请戳官方文档
如果你想适配,但苦于没有参考,想找个参考的话,可以看一下我的开源项目成都信息工程大学 小爱课程表适配
原理
下面本文的重点来了,先简单介绍一下小爱课程表这个适配功能原理:小米的工程师们提供了一个webview
,让开发者可以在页面上加载出你的课程表,然后通过你使用官方提供的chrome浏览器插件
开发好的scheduleHtmlProvider.js
和scheduleHtmlParser.js
解析出符合小爱预定义好的规范的json
数据,点击一键导入
之后,通过https请求
提交到小米的服务器,然后小爱课程表根据这个json
数据进行课程表的渲染,单就原理而言,并没有什么太大的问题,但是坑就坑在Android
的webview
,这个无法渲染出js动态生成的课程表(目前已知金智和树维的教务系统,无法渲染出来,登陆之后会白屏,就像下面这张图一样)
博主也是在适配完了我们学校的小爱课程表之后,才发现这个问题的,这适配完了,用不了的情况,就很不舒服,于是尝试寻找解决办法
破局
在理解了小爱课程表适配功能的原理之后,发现,我们缺少的其实就只有提交到小米的服务器这一步,所以从另一个角度来看,我们完全可以自己提交课程数据给小米的服务器,于是说干就干,抓个包来看看小爱课程表提交到小米的服务器的数据是什么样子的,在这里我选用的抓包工具是小黄鸟
配置小黄鸟
下载并安装小黄鸟,GitHub传送门
打开小黄鸟,安装证书等等
设置小黄鸟的目标应用为小爱同学
开始抓包
打开小爱同学,添加一条测试课程看看
发现提交课程的报文如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17POST /course/courseInfo h2
Host: i.ai.mi.com
content-length: 272
access-control-allow-origin: true
user-agent: Mozilla/5.0 (Linux; Android 10; MI CC 9 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.101 Mobile Safari/537.36
content-type: application/json
accept: */*
origin: https://i.ai.mi.com
x-requested-with: com.miui.voiceassist
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
referer: https://i.ai.mi.com/h5/precache/ai-schedule/
accept-encoding: gzip, deflate
accept-language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
{"weeks":"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20","name":"测试","position":"","teacher":"","sections":"2","day":1,"style":"{\"color\":\"#00A6F2\",\"background\":\"#E5F4FF\"}","csId":2371853867,"userId":123436229,"deviceId":"a88374c981cf771f8360dabcde4c3574"}
分析报文
接口地址:https://i.ai.mi.com/course/courseInfo
接口传递的json及其字段含义:
1 | { |
比较
将抓取到的接口和我们按照官方文档渲染出来的json
格式比较一下:
可以发现,sections和weeks字段
有些许的不同,另外,缺少了style,userId,deviceId字段
,基于此,我们可以稍微修改一下js
解析出来的格式,并且加入缺少的字段,然后模拟请求提交给小米的服务器即可
修改json格式:
- “weeks”:由数组改成字符串,逗号分割
- “sections”:由数组改为字符串,逗号分割
- 增加userId,deviceId字段,值为vConsole的LocalStorage中的相关值
- 增加style字段,可以给默认值为
"{\"color\":\"#00A6F2\",\"background\":\"#E5F4FF\"}"
,或者自定义,建议默认值,不会影响负一屏的效果,但缺点就是不够个性化
模拟请求
原理写了一大堆,相信大家应该都懂了,所以这里只给出一个写好的python脚本,依赖python3,requests
1 | # -*- coding:utf-8 -*- |
使用方式
可以直接使用我的这个开源项目,前提是你们学校的课程表已经适配了,不然你需要先适配
成信大学子
- clone 适配小爱课程表的项目到本地
- 登陆教务管理系统,保存课表html
- 打开小爱课程表,在vConsole的LocalStorage中拿到userId和deviceId;vConsole,可以通过连续点击荣誉coder下方空白区域调出
- 拿到课表的table的HTML源代码放到course_table_demo.html的body中
- 双击course_table_demo.html,用浏览器查看,并在console中将打印出来的课表json复制出来
- 修改上面的python脚本的相关配置为自己的,然后运行python脚本
- enjoy it
其他学校学子
- 适配小爱课程表
- 接下来就和上面一样了
致谢
部分思路来自于: