利用Python获取正方教务系统在校成绩 水深无声 2022-05-31 09:44 342阅读 0赞 今天要说的一个小项目是利用Python来获取正方教务系统的在校成绩,说白了这就是一网络爬虫。做之前也有上网搜索了一下资料,这里就给一个总体的思路吧,就以我学校的作为例子。不过遗憾的是并没有添加验证码的破解功能,还需要手动输入。希望能够帮助到一些朋友。 以下的代码全部基于**Python3**。 **开始之前:** 1、请自行安装[BeautifulSoup][] 用于网页解析 2、请自行安装[PrettyTable][] 用户格式化输出 3、请自行安装[PIL][] 用于打卡图片。这也是日后想增加OCR识别的一个部分 **观察:** 做好了以上的准备工作之后,接下来就要观察一下我们的教务系统,观察以下登陆的表单: ![2018021921334147][] ![20180219113850860][] 可以发现表单被提交至default2.aspx,验证码是一个单独的网页,为CheckCode.aspx,表单提交页应该是一样的,就是验证码,各个学校会有不同。 在利用抓包工具可以发现浏览器向客户端提交了如下图数据: ![20180219113611413][] 总共提交了10个参数(因学校而异,不过应该都差不多) 这有值的5个参数分别对应:\_VIEWSTATE,用户名,密码,验证码,登陆角色(学生)。剩下那些没有值的在后期构建表单的时候也需要创建 接下来我们进入到查询全部成绩的页面,页面也因学校而异 ![20180220114301763][] 通过抓包工具获得页面地址,如下图方框中的 ![2018021911012590][] 这时要记下上图方框中的地址,再一次观察表单提交的数据: ![20180219114318444][] 这一次是6个参数。 其中第一个是\_VIEWSTATE,第二个是学年,第三个是学期,紧接着后两个参数未知,照着写就好,最后一个参数是【在校学习成绩查询】按钮URL编码后的值 不知道大家有没有注意到在上面两次查看表单数据的过程中都出现了一个参数叫\_VIEWSTATE?而且两次都还不一样,所以我们在模拟的时候要分两次获得\_VIEWSTATE。 最后我们再看一眼HTTP请求头 ![20180219184316498][] 看到那个红框了吗,这个Refer参数很重要,要记得添加,否则就会出现302跳转,然后显示一行 ![20180219114844692][] 因为这个参数在这里是用来防止盗链的,不信的话可以用Chrome的ModHeader插件来试一试 ![2018021918450053][] **思路:** 1、总体:借助Python的http.cookiejar.CookieJar对象,使用urllib.request.build\_opener来构建一个带有Cookie的opener,然后就使用这个opener来访问所有的页面,最后输出结果就好了。 2、验证码的获取与显示:因为我们是要让用户输入验证码,所以我们需要把获取到的图片以二进制流的方式写入文件。在利用PIL的open方法将图片文件读入,创建图片对象,最后用show方法调用系统的图片查看器显示图片。代码片段: res = opener.open('http://example.com/checkcode.aspx').read() with open('code.jpg','wb') as file: file.write(res) img = Image.open('code.jpg') img.show() 3、\_VIEWSTATE的获取:这个就要利用正则,把网页的html读取下来之后,利用以下正则表达式进行匹配 viewstate = re.search('<input type="hidden" name="__VIEWSTATE" value="(.+?)"',html) params['__VIEWSTATE'] = viewstate.group(1) 这个params为我们要提交的表单数据字典 4、关于BeautifulSoup4的解析:我当时是这样进行分析的,我把网页读取出来之后,构造了一个BeautifulSoup对象 soup = BeautifulSoup(response.read().decode('gb2312'),'html.parser') 这里要注意一下后面的html.parser是解释器,要加上,然后要根据各自教务系统的编码进行解码 接着使用CSS过滤器找到成绩表格 html = soup.find('table',class_='datelist') 它会返回一个Tag对象,这个对象是可迭代的,所以我们可以使用for语句来遍历我们的表格,来获取每一行的内容,最后在根据需求进行筛选,这个就要因人因学校而异了,因为每一个学校的表格都不太一样。 5、PrettyTable输出:说一点,输出时要使用str()这个BIF进行转换,不然有可能会报错 **代码**: [https://github.com/mgsky1/ScoreHelper/blob/master/src/getScore.py][https_github.com_mgsky1_ScoreHelper_blob_master_src_getScore.py] **附:** 我在源码中还使用Pickle,用二进制的方式存储用户数据,这样可以避免烦人的多次输入 [BeautifulSoup]: https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html [PrettyTable]: https://pypi.python.org/pypi/PrettyTable [PIL]: http://www.pythonware.com/products/pil/ [2018021921334147]: /images/20220531/77765d1a19b747cba05c5821f0d66280.png [20180219113850860]: /images/20220531/c25e062442c141359e3c406c9bd64f12.png [20180219113611413]: /images/20220531/7415f0b545c448ea9b50242badf204ad.png [20180220114301763]: /images/20220531/770e16cd80a146ca85b359c468dfd8fb.png [2018021911012590]: /images/20220531/df2c4c24bcd148c39556889b73c45fa3.png [20180219114318444]: /images/20220531/9a56b32d1eff45baadc2ebfe858c53d5.png [20180219184316498]: /images/20220531/d4f2db536f9a4a95959ddf640065fd11.png [20180219114844692]: /images/20220531/75a60e8f86ad4ff4b996c56c9fcbfe3f.png [2018021918450053]: /images/20220531/eb05b5754d104a94ab82fcddf6f5cb24.png [https_github.com_mgsky1_ScoreHelper_blob_master_src_getScore.py]: https://github.com/mgsky1/ScoreHelper/blob/master/src/getScore.py
还没有评论,来说两句吧...