新正方教务系统小程序的实现杂谈(上篇-API篇)

这篇文章主要分享因为不可抗力这么多天在家里做这个项目过程中遇到的些许问题,以及怎么去解决的思路,所以可能老哥们没有什么实质性的收获,就当我写个日志给大家看看图个乐。当然,学校教务系统是新正方教务系统的老哥可能会好一些。
首先,上篇就说说后端的API吧,也是整个项目最重要的部分,技术底子是Python+Django以及uwsgi和nginx的基本配置​,本质是前后端分离的分布式爬虫。
先看API的效果:

一、post个人信息,成绩,课表,学业情况以及课程通知:

个人信息

个人信息.png

成绩

成绩.png

课表

课程.png

学业情况

学业情况.png

消息

消息.png

二、post已选课程,板块课课程​,选课和退课(实现中):

已选课程

已选列表.png

选课列表

选课列表.png

三、录取查询,one一个每日一句,项目配置config:

录取查询

录取.png

每日一句

one.png
这样,基本上教务系统能做的事儿,咱api也能做了。
——————————分割线——————————​
下面是一些问题和解决思路,属于个人的一些废话,如果没有兴趣的老哥可以直接翻到最下面一段或者去看下篇关于小程序的实现篇了。

(1)隐私信息问题

作为有节操(可能)的个人开发者,​在别人用你的api时,是不应该收集别人的隐私信息的,但是在一丢丢信息都没有的情况下,也不利于开发(比如当初折磨我的,一个同学其实是处于休学状态,但他一直查课程,于是我的Server酱(一个免费的mqtt服务,给程序员通过微信服务号提供服务器异常报警)也一直疯狂报错list out of range(一种数据错误)那是凌晨一点...)
那么,还是建一个数据库吧,这方面用的django原生兼容的sqlite3​(一个简洁的数据库)就够了 ,每个同学第一次登录都会在里面存入姓名学号和班级(休学是没有班级的)以及cookies(不懂的老哥可以理解成网站登录账号时候点的“自动登录”,浏览器会保存一串神秘代码,浏览器通过这段神秘代码可以在一定时间内直接进入到已登录状态)的字段,还有最后更新cookies时间,总登录次数等。这样一来,在不接触到同学的隐私信息(比如密码,手机号等)​下,一方面可以做用户统计,一方面可以在出现未知错误后用cookies放到自己写的调试工具里看是出了什么问题,一方面根据班级以后也能做一个类似年终总结的东西(我都想到那后面去了...)
不过有心的老哥还是发现了,存储了cookies,在一天时间内(我校教务系统cookies存活时间),如果有心,还是能轻易通过这个去获取该同学的隐私。这种情况的话,就看开发者人品了吧,后期学校觉得有用的话,我会将该项目托管给学校,毕竟怀璧其罪,就当给信息化做个贡献。

​(2)各种环节的异常处理

这玩意儿是真的把我给整吐了,网络爬虫的不稳定性​熟悉的老哥肯定知道,更何况是新正方教务系统这种极其玄学(同一网络不同设备,有的要一分钟才有数据,而有的却秒加载)的站,简直是爬虫噩梦。
所以,为了让同学体会不出这种感觉,那么下面就是try和except(python里面的异常处理语句)了:

  1. 首先,就是登录,​也是最核心的部分,通过登录获取到cookies,才有了后续的各个查询。也是最容易访问超时的部分,上面说过玄学问题,所以我的解决办法是,设置10秒的超时,超过时间没有获得cookies就断开本次访问,然后重试,一共重试三次,也就是说,运气极差的情况下,要经过30s,还不一定能登录成功。但经过200多个本校同学的一轮测试,发现最差都是在第三次访问时就登录成功,所以暂定这个办法是最优解。
  2. 然后,就是各个数据的查询了​,这方面基本上不会出问题,因为是带cookies请求访问的,所以除非教务系统宕机,一般请求时间不会超过5s(事实上大部分是0.几秒),但是要考虑cookies失效的问题,如果cookies失效,是会抛出一个固定的错误的,那么我们在抛出这个错误时,写上重新登录并更新数据库cookies且继续返回请求数据的功能,这样问题也就马马虎虎解决了。

​(3)数据处理

举个例子,新正方教务系统的各个字段和参数的名字有多么“浅显易懂”​:xnm,xqm,kcmc,jxb☞学年名,学期名,课程名称,教学班。如果你觉得这还算勉强可以理解的话,那JYXDXNMMC,DQSZBJMC☞建议修读学年名名称,当前所在班级名称。这种拼音缩写是真的要命!
所以我不得不做了数据处理,大致就是把获取到的json数据(一种比较通用的数据格式)​,用代码挨个循环遍历,极其头疼的从拼音缩写翻译过来后把正确的英文键名给它赋上去成为新的json数组,就是如下图的变化:
数据处理
就是文章开头的数据格式,这样就方便看多了。​

(4)​日志

uwsgi也会自动写服务器日志,但是那看起来太杂太乱了​,是这样的:
所以,还是要自己写,首先创建一个文件夹,思路就是,在每个获取数据的代码后都加上写入日志的代码,有人在当天第一个访问​某数据时,会自动建立当天2020-02-24.log这样的日志文件,代码函数和日志内容是这样的:
函数
日志内容
顺带提一句,日志和异常处理是密不可分的。

(5)代理IP

这个也挺头疼的,因为新正方是有反爬虫的,虽然不那么厉害,但还是有,就是说,如果一个IP频繁访问它的话,是会出现max receive,被拒绝访问的,于是我不得不在每个请求后面加上proxies(代理访问)参数,用的是网上的免费代理,然后每隔一段时间更新(惨)
——————————分割线——————————​
​于是api就在我一个人迷迷糊糊懵懵懂懂的状态下算是写了出来,不完美不完善的地方还很多,以致于每天都要或多或少对它进行修改...
但这次经历对我来说也挺重要的,寒假前对Python爬虫的运用只是处于能爬个天气这种基本操作,框架也只接触过Flask而没有接触Django。能感受到自己明显的成长是令人可喜的。
如果有老哥学校也是一样的教务系统,欢迎一起交流,至于开源,后面肯定是会开的,不过等我改的差不多再说嘛,接下来就去康康我下篇小程序篇吧~

本文链接:

https://www.zaigie.com/archives/208/