因为2020年疫情的原因,学校让每位同学在家上课并且每天上报健康数据,但是我上报了几次觉得很麻烦并且容易忘掉,遂写了一个python程序,帮助提交身体健康数据[注1][注2]。
我已经使用了大约1个半月左右了,经历了几次版本迭代,目前可以实现多账户提交,这里分享下当时的思路,如有不当之处,请予指正,E-MAIL:i.ldy@qq.com
。
目标
针对“智慧山水”APP的“每日健康上报”功能实现自动上报数据。
思路
大致思路:
- 获取提交数据的API
- 每天自动向学校服务器发送数据
第一步、确定提交的数据是以怎样的形式被传输到学校服务器的
因为学校是让我们下载了一个安卓APP,所以在这一步中,我使用了手机端的抓包软件(当然也可以使用更专业的PC端的抓包软件),访问提交信息的页面并填写提交了数据,抓包到了一个网址链接[注3]。
抓包到的链接:http://pubinfo.sdwcvc.cn/Xxtb/dailyRecord?userid=我的学号
经测试,可以省略掉问号以及之后的内容。
PC端浏览器访问这个网址,跳转到了统一身份认证页面http://sso.sdwcvc.cn/(当时学校第一次启用智慧山水APP,所以我这里猜测是学校平台的PC端,后证实确实是),可以登录自己的账号。我当时为了速度,就使用了手机验证码登录。
登录账号后跳转到了 智慧校园综合服务门户http://portal.sdwcvc.cn/,我看到了与手机端类似的功能按钮与设计,但是并没有提交信息的入口,仅存的“健康上报管理”按钮还是灰色的。
尝试使用浏览器的“检查”功能,没有找到入口链接,所以我尝试再一次访问之前抓包到链接,这次可以正常查看提交信息的页面,发现原来就是提交页面,而且上边显示我今天已经提交。
我试着点击了“我要修改”,发现来到了正式的提交页面。之后我查看网页源代码,发现因为当天已经提交了,所以正式页面需要点击一次按钮才能被显示。如果当天未提交,则服务器返回的网页不会提示已经上报,这点可以作为当天初次提交还是修改的依据。
然后我开启了浏览器“检查”功能,打开NetWork选项卡,点击了网页的“提交修改”的按钮,发现抓包到了个好东西。
GET方式的请求,且Request URL是键值对的形式传输了数据,不难猜到这就可能就是传输的健康信息。
链接(已脱敏):
http://pubinfo.sdwcvc.cn/Xxtb/saveRecord?id=924680&mqjk=%E5%81%A5%E5%BA%B7&jrjk=%E5%81%A5%E5%BA%B7&city1=%E5%8C%97%E4%BA%AC&city2=%E5%8C%97%E4%BA%AC&city3=%E5%8C%97%E4%BA%AC&sfwc=0&sfjc=0&sfhb=0&zb=%E4%B8%8D%E6%B8%85%E6%A5%9A&jchz=%E5%90%A6&other=%E8%BD%BB%E5%BE%AE%E5%92%B3%E5%97%BD%EF%BC%8C%E4%B8%8D%E5%8F%91%E7%83%AD%EF%BC%8C%E6%8B%BF%E4%BA%86%E8%8D%AF%E3%80%82
然后我们鼠标向下滑动,发现了浏览器已经帮我们做了解码。
为了避免服务器端接受信息产生歧义,url通常会被浏览器进行编码,所以这里我们看到的了好多%这样的url。
试着手动复制url到浏览器地址栏并访问,返回了这样的数据。
由此可以确定这就是我想要找到的接口。
第二步、编写代码
拿到了数据接口,开始用Pyhon写爬虫程序。
第一个版本是完全没有封装、没有优化,仅仅只有提交信息的功能。身体健康信息是用一个字典变量进行保存的,而且是写死在了代码里面。请求头数据使用的是浏览器抓包到的Request Heades信息。
登录获取Cookie
试了几次提交我发现Cookie的可用时间比较短,PC端退出了就失效了,于是我尝试每次登录获取Cookie然后再提交信息,于是我去了网站登陆页面 智慧校园综合服务门户http://portal.sdwcvc.cn/。
发现了三种登录方式。
后两种都不能实现无人值守,所以我决定使用用户名(学号)登录。
模拟发送登录请求获取Cookie
与上边抓包获得数据提交的接口同理,这次输入完用户名和密码后,点击登录之前要先打开浏览器的“检查功能”,切换至“NetWork”选项卡,然后再点击登录,会发现已经成功登录,并抓包成功,且浏览器跳转到了“智慧校园综合服务门户”页面
可以发现,发送请求使用的POST方式,并获取到了url:http://sso.sdwcvc.cn/index.php?rid=verifyWebUser
滑动至Headers选项卡最下面,找到了发送的数据。
经测试,仅需使用username
用户名(学号)和password
密码两项即可登录。
从登录到提交中间时间保持登录状态,我使用的方法是创建一个requests.session()
实例对象,使用这个实例对象进行登录以及提交健康数据。
实际过程中我还请求了提交页面,查看当天是否已经提交成功了。
传输的信息中key的含义
我尝试修改了提交的信息,查看了网页源码,经过多次验证确定了每个key的含义
url中的每个key的解释如下
key | 含义 |
---|---|
id | 表单id,如果是当天初次提交,id为空即可,会创建一个新的表单。当天提交后再次访问提交页面,返回的页面中会包含一个隐藏的输入框,其value就等于当天已经提交表单的id(Xpath:/html//input[@name="did"]/@value )。如果修改已经提交的信息则提交时id为此值即可。 |
mqjk | 1.目前个人身体健康情况 |
jrjk | 2.一起居住的家人身体健康情况 |
city1 | 3.目前所在城市:省份 |
city2 | 3.目前所在城市:市 |
city3 | 3.目前所在城市:县区 |
sfwc | 5.今天之前14天内是否有外出 |
sfjc | 6.是否有聚餐或聚众 |
sfhb | 7.自2020年01月10日起,是否在湖北停留或路过,是否接触过来自湖北的人员 |
zb | 4.当前所居住小区或村庄是否有官方公布的新型冠状病毒确诊者或疑似者 |
jchz | 8.是否接触过新型冠状病毒的确诊者或疑似者,以及新型冠状病毒的密切接触者 |
other | 9.其它需要说明的事项。任意字符串即可 |
**注:**除other以外,其他都需要严格按照提交页面的内容选项来设置。
源码与GitHub仓库
目前新版本程序可以支持多账户使用,不过我使用的还是之前的老版本,因为够用所以就没有动力去换,而且新版本可能有BUG……,有机会再进行测试吧。
这个项目在我没有学习Git时就已经迭代好几次版本了,所以Git仓库的没有之前版本的代码。后期考虑新建个分支用来保存旧代码留作纪念。
GitHub仓库:https://github.com/imldy/health-data-post
智慧山水平台好像要更新了,我看到已经在测试新的提交页面了(2020年4月10日)。有兴趣的小伙伴可以参与进来哦:blush:。
后记
后续可能会出一个文章详细介绍代码,欢迎收藏我的博客:blush:。
[注1]:只会提交提前设定好的身体健康数据,所以若身体情况发送变动必须及时更新数据,否则学校将会收到错误信息,防疫工作也会受到影响。 [注2]:若无特殊说明,除文件名之外,以下“上报”等同于“提交”。
[注3]:当时我填写并提交了身体信息,但是我并没有注意提交数据的API链接,后边在网页端才发现并注意到了。 [注4]:仅交流技术,如侵犯到您的权益请联系我进行删除。