1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 枯燥的寒假生活(一) python爬虫模拟登录whu老教务系统获取期末考试成绩(已失效

枯燥的寒假生活(一) python爬虫模拟登录whu老教务系统获取期末考试成绩(已失效

时间:2022-11-22 19:21:12

相关推荐

枯燥的寒假生活(一) python爬虫模拟登录whu老教务系统获取期末考试成绩(已失效

python模拟登录老教务系统(.6.24更新)

一、写在前面

之前用爬虫爬取的都是静态网页html中的内容,但是大多数时候需要动态处理网页爬取数据。因为学校出成绩太慢了,每次都自己打开浏览器登录太过繁琐,于是想要用爬虫直接抓取期末考试的成绩hhhhh,经过很多天的摸索最终勉强算是成功了吧。

看明白这篇文章需要了解

requests库相关知识 , session和get,post等

BeautifulSoup相关知识

一点点浏览器自带的检查功能的用法

二、登录教务系统

了解教务系统登录时的操作

我武的老教务系统网址是:http://bkjw./

朴实无华的登录界面,输入学号,密码,和验证码。

简单抓个包(直接用浏览器的检查就行,这种小事情就不用burpsuite了)。因为并不想立刻登录成功,只是想要看一下发过去的request是什么样子的,所以我的验证码就直接写1234了。密码写的123456的,总不能告诉你们我的密码吧。

这个这么长时间的包,肯定是主要内容,点开康康

果然,是向http://bkjw./servlet/_90e916fe3这个网址post了一个表单,表单里有时间戳,jwb还不知道是啥,id是学号,pwd一看是加密过的密码,xdvfb是1234的话,那应该就是我们输入的验证码。jwb虽然不知道是啥,但是一看就是url编码,转换以后发现就这(武大本科教务系统)

然后我们已经知道表单的构造了,到时候直接按照这个来构造payload就行,基本思路就是headers搞一下,表单搞一下,再发送到相应的网址就行。目标网址

经过几次重复登录发现,每次请求的网址其实后面部分是不一样的,并且在登录成功时status code是301, 也就是其实会自动重定向,暂时我每次都使用同一个网址没有出现问题,这里暂时还不知道怎么处理, 随机选取多个网址发现最后都能运行,也就没有去深究原理,欢迎大佬赐教.验证码

因为不会用OCR来自动识别, 这里采用原始但是也还是可以接受的手动输入验证码(这么一步我个人还是可以接受的)

所以思路也相当明确, 找到验证码的链接, 然后保存到本地, 然后在本地显示, 最后手动输入 , 并且整合到表单中, 提交表单登录.所以要用到PIL库

首先要找到验证码的网址, 不用多说, 一手检查, 定位到验证码的位置

查看源代码发现是在html中的

所以到时候直接在代码中用BeautifulSoup找到这个链接, 进行相应的处理拼接即可得到验证码的链接.然后进行保存显示和输入验证码即可.

在我的代码中此部分用了两个函数实现

def getCaptcha(self):r = self.s.get(self.url) # 第一次请求获取验证码的地址demo = BeautifulSoup(r.text, 'html.parser')a = demo.find_all('img')captcha_img = a[2].attrs['src']captcha = self.refer + captcha_img # captcha是验证码的网址return captchadef inputCaptcha(self):img = self.s.get(self.getCaptcha(), stream=True) # 第二次访问下载验证码到本地并展示with open('checked.gif', 'wb') as f:f.write(img.content)image = Image.open('checked.gif')image.show()self.login_data['xdvfb'] = input("验证码:") # 输入验证码并放进表单中

其他内容

headers和表单的构造就直接按照抓包得到的来就行

下面直接截取我的类中的init做展示.

def __init__(self):self.url = "http://bkjw./servlet/b89d79056" # 用于重定向的urlself.refer = 'http://bkjw.' # 教务系统限定了refer是这个,并且也可以作为一些请求的前半部分self.s = requests.session() # 创建一个新的会话self.s.headers.update({"Connection": "keep-alive","Upgrade-Insecure-Requests": "1","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, ""like Gecko) Chrome/87.0.4280.141 Safari/537.36","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,""image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","Referer": "http://bkjw./stu/stu_score_parent.jsp","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9",'referer': self.refer}) # 更新headers,防反爬self.login_data = {"timestamp": "1610800439978","jwb": "%E6%AD%A6%E5%A4%A7%E6%9C%AC%E7%A7%91%E6%95%99%E5%8A%A1%E7%B3%BB%E7%BB%9F","id": "302180xxx你的学号","pwd": "这里填你之前抓包到的加密后的你的密码","xdvfb": "" # 提交的表单的数据}

以上步骤完成以后,就能够登录教务系统了,不过我们还需要得到我们的成绩.

三、获取成绩

我们需要得到获得成绩数据的真实请求网址,所以我们用检查发现其实成绩查询这部分内容是用一个iframe嵌套显示的,不过真实请求网址也已经在src中体现了出来(还好,我武的教务系统没有用js去加载它)

进入以后发现这个是课表的src不是成绩查询的,不过受此启发,成绩查询应该也对应了某个jsp文件,直接去html源代码里搜索jsp

凭借超凡的语文能力和英语素养,我猜测这个stu_score_parent.jsp一定是成绩查询的网站了吧。

不出所料

本以为大功告成的我,打开html源代码准备分析数据的提取时发现,这其实是一个动态加载的网页,在源代码中并没有想要的数据。

于是又是枯燥的抓包过程,最终发现真实的请求网址,以及它的参数,其中的csrftoken我们没有办法生成,year应该是学年,term是学期,这两个参数为0应该是表示所有学年所有学期。scoreFlag不知道是啥,试了下0没问题,t是现在的时间,不过是需要处理一下再拼接的。

在源代码中寻找想要的csrftoken,运气不错,真的有,只需要处理一下时间即可。所以最终所有都有了,将以上的过程整理和拼接就能得到一个python模拟登录教务系统成绩查询的小程序啦。

四、运行结果

成绩一门没出就离谱。

五、代码分享

/blue-vegetable/whu_score_spider

虽然没什么技术含量,但还是厚颜求dl们点个赞鼓励一下本菜吧

六、写在后面

其实用梦想珈看成绩,或者从信息门户进入教务系统,都是可以的,这里更多是为了能够提高对爬虫的理解,实现用爬虫登录和获取一些动态加载的数据.

本篇文章其实更多是分析怎么做到,而很少有具体的实现,因为,实际上代码不过百行,知道这个原理敲出这个简单代码只是时间问题

当然有很多地方还需要继续钻研,比如对于目标网址的获取,教务系统所使用的密码加密的方法,如何实现用ocr识别从而全自动不用自己手动识别验证码或者能够直接绕过这层验证?能否用微信小程序的形式完成这个功能等等.这些就留给后面的时间去解决吧.

枯燥的寒假生活(一) python爬虫模拟登录whu老教务系统获取期末考试成绩(已失效 老教务系统增加了新的反爬 老教务系统已停用)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。