之前已经完成了验证码的识别
就想进一步把绩点也抓取下来吧
毕竟我的手机没有一个浏览器可以保存xuanke网的登录状态
绩点页面抓取
总览
我的目标是要抓取绩点页面并解析成一串JSON字符串返回,我把每一步都独立成一个函数并以promise的形式完成。
1 | function GPA(token, cb = function(){}) { |
这一步没什么,主要是先获取cookie并保存下来
1 | let store = {}; |
目标路径是/CheckImage。
1 | const opts = { |
获取到图片是buffer的形式,再调用我上一篇博文写好的parseCAPTCHA.js解析即可。
这里之前限制了必须是读取文件路径,所以我又对此稍稍改动了一下parseCAPTCHA.js文件让其支持读取buffer,因为使用的Jimp包本身提供了读取buffer的方法。
Post用户名密码和验证码
这里的目标是:“tjis2.tongji.edu.cn/amserver/UI/Login”
会有5个Post参数要求,分别是
- goto
- gotoOnFail
- Login.Token1
- Login.Token2
- T3
goto是用户名和密码正确会接着跳转的页面
同理,gotoOnFail是错误要跳转的页面
Token1和Token2是用户名和密码
T3是四位验证码的字符串
此处的response会带有4个set-cookie的字段,然而其中一个是立即失效,剩余三个需要存储起来,之后需要使用。
分别是以下三个字段:
- AMAuthCookie
- amlbcookie
- IPlanetDirectoryPro
可以根据response的headers的Location字段判定是含有’pass.jsp’还是’deny.jsp’来明确用户名和密码是否正确,然后做异常处理。
跳转到验证码判定
如果上一步的用户名和密码正确,会跳转到’xuanke.tongji.edu.cn/pass.jsp?checkCode=${验证码}`
同以上一步,根据response的headers的Location字段是否含有’index.jsp’来判断验证码是否识别正确,错误要做异常处理。如果含有’index.jsp’证明验证码错误,跳转到登录页。否则成功。
进入登录后的首页
带着coookie
目标是’xuanke.tongji.edu.cn/tj_login/frame.jsp’
发送一个不知用意何在的GET请求
获取绩点页面
带着cookie
GET请求路径是:
‘xuanke.tongji.edu.cn/tj_xuankexjgl/score/query/student/cjcx.jsp?qxid=20051013779916&mkid=20051013779901’
这里response的data还是用Buffer处理,我使用了iconv-lite来将GBK的编码转成UTF-8,然后使用html-minifier将返回的html压缩预处理,去除空行和空格,方便之后的处理。
解析绩点html页面
使用了jsdom包来提取页面信息
这里的页面没有明显的id或者class可以直接提取,大部分信息我都要用到parentNode或者nextSilbing来获取我要的节点。
具体的提取方法,大家可以自己去看看页面结构,也许有比我更快的提取方法。
Electron
东西都爬完了当然想做成能使用的产品,想到了js写客户端的两个轮子分别是Electron和NW.js,觉得Atom使用的Electron可能更有优势于是去试了一下,把页面写好了之后觉得用客户端还不如直接打开edge上去看呢。。于是还是打算做成普通的网页吧。
Web页面
首先想到了browserify,天真的想着这样可以把所有东西都在浏览器跑了。
然而,咋就忘记了跨域的问题呢。顿时觉得自己还是智障。
于是还是按普通的做法,开个服务器,写个post的API。
戳这里
不想自己服务器再开一个后台
于是只是把这个API加到novastar的API中去了
微信小程序
在写完Web页面+后台API之后,在同心云上看到有人做了一个查电费的微信小程序(虽然我一直查不了
但还是觉得我也可以写一个玩玩,特别是现在小程序开放给个人用户了。
看到wxss就是css,wxml就是html的时候,觉得蜜汁神奇。
小程序整体的开发是按照React的思路,单向数据流。数据绑定之后可以通过一个setData()的函数来更新页面。笔者觉得如果熟悉React的话应该直接就上手了。
唯一要提的一点是发现网络请求一定要https协议,当时心想,天哪,SSL好贵啊大概是做不成了,然后去网上一搜,发现阿里云居然可以免费申请SSL证书,而且一个阿里云账户可以申请20个免费证书!非常震惊。
因为有人觉得我在偷密码XD,在这里贴出整个请求的代码,当然其实这还不够,所以觉得我偷密码的就不要用了orz。。
做这个小程序的其中一个原因是我的手机浏览器包括chrome、微信内置的等等都不能保存xuanke网的登录状态,期末的时候没电脑很难查。
以下是微信端发请求调用的函数,传入token,用户输入的学号密码,cb是回调函数。
1 | function getGPA(token, cb) { |
当时novastar是采用了node的express框架,这里直接添加了一个API,调用的GPA函数就是本文最上面代码的函数。
1 | router.post('/gpa', function (req, res) { |
这里也放出一个可运行的Node版本戳这里
1 | $ npm install |
访问http://localhost:5321
即可
不得不说现在小程序审核速度挺快的,我审核了两次都是24小时内就出结果了。(虽然五一的时候停了
同济大学绩点查询微信小程序已经审核通过上线了,欢迎各位校友使用:)
在小程序搜索’同济大学绩点查询’即可找到,也可扫描下方二维码↓