2024年最全用Python模拟登录学校教务系统抢课(2),2024年最新头条面试算法题

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

分析r返回的文本信息

发现验证码的标签的资源地址为 src=“CheckCode.aspx” ,我们可以直接requests然后下载验证码图片,下载图片的一种优雅的方式如下

  1. def \_\_get\_code(self):
  2. request = requests.get(self.\_\_real\_base\_url + 'CheckCode.aspx', headers=self.\_\_headers)
  3. with open('code.jpg', 'wb')as f:
  4. f.write(request.content)
  5. im = Image.open('code.jpg')
  6. im.show()
  7. print('Please input the code:')
  8. code = input()
  9. return code

上面的代码把图片保存为code.jpg,Python有一个Image模块,可以实现自动打开图片

这样验证码就展示出来了,我们人工输入或者转入打码平台皆可

登录数据的构造

这是上面抓的登录post的数据包,

640?wx_fmt=jpeg

发现有信息无法被解码,应该是gb2312编码,查看解码前的编码

640?wx_fmt=jpeg

然后将不能解码的代码复制能够解码的地方

发现%D1%A7%C9%FA编码解码后为学生

这也就对应了学生选项的登录

学号和密码和验证码能够显而易见地知道是哪些信息,但是我们发现有__VIEWSTATE这一项

查找一下,这是一个表单隐藏信息,我们可以用BeautifulSoup库解析可以得出该一项数据的值

640?wx_fmt=jpeg

这是完整的登录数据包,

  1. def \_\_get\_login\_data(self, uid, password):
  2. self.\_\_uid = uid
  3. request = self.\_\_set\_real\_url()
  4. soup = BeautifulSoup(request.text, 'lxml')
  5. form\_tag = soup.find('input')
  6. \_\_VIEWSTATE = form\_tag['value']
  7. code = self.\_\_get\_code()
  8. data = {
  9. '\_\_VIEWSTATE': \_\_VIEWSTATE,
  10. 'txtUserName': self.\_\_uid,
  11. 'TextBox2': password,
  12. 'txtSecretCode': code,
  13. 'RadioButtonList1': '学生'.encode('gb2312'),
  14. 'Button1': '',
  15. 'lbLanguage': '',
  16. 'hidPdrs': '',
  17. 'hidsc': '',
  18. }
  19. return data

登录

如果登录完成了,如何判断是否登录成功呢?我们从登录成功返回的界面发现有姓名这一标签,而我们等一下也是需要学生姓名,所以我们用这个根据来判断是否登录成功。

640?wx_fmt=jpeg

代码如下,进行了验证码用户名和密码的提示信息判别

  1. def login(self,uid,password):
  2. while True:
  3. data = self.\_\_get\_login\_data(uid, password)
  4. request = requests.post(self.\_\_real\_base\_url + 'default2.aspx', headers=self.\_\_headers, data=data)
  5. soup = BeautifulSoup(request.text, 'lxml')
  6. try:
  7. name\_tag = soup.find(id='xhxm')
  8. self.\_\_name = name\_tag.string[:len(name\_tag.string) - 2]
  9. print('欢迎'+self.\_\_name)
  10. except:
  11. print('Unknown Error,try to login again.')
  12. time.sleep(0.5)
  13. continue
  14. finally:
  15. return True

获取选课信息

接下来就是获取选课信息了,这里我们以校公选课为例子,点击进去,进行抓包,headers没有什么好注意的,我们只用关注get发送的包即可

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

发现有学号与姓名与gnmkdm这一项,姓名我们需要编码为gb2312的形式才能进行传送

这里我们注意headers需要新增Referer项也就是当前访问的网址,才能进行请求

  1. def \_\_enter\_lessons\_first(self):
  2. data = {
  3. 'xh': self.\_\_uid,
  4. 'xm': self.\_\_name.encode('gb2312'),
  5. 'gnmkdm': 'N121103',
  6. }
  7. self.\_\_headers['Referer'] = self.\_\_real\_base\_url + 'xs\_main.aspx?xh=' + self.\_\_uid
  8. request = requests.get(self.\_\_real\_base\_url + 'xf\_xsqxxxk.aspx', params=data, headers=self.\_\_headers)
  9. self.\_\_headers['Referer'] = request.url
  10. soup = BeautifulSoup(request.text, 'lxml')
  11. self.\_\_set\_\_VIEWSTATE(soup)

注意到上面有一个设置VIEWSTATE值的函数,这里等下在选课构造数据包的时候会讲

模拟选课

随便选一门课,然后提交,抓包,看一下有什么数据发送

640?wx_fmt=jpeg

640?wx_fmt=jpeg

前三个值可以在原网页中input标签中找到,由于前两项为空,就不获取了,而第三项我们使用soup解析获取即可,由于这个操作是每请求一次就变化的,我们写成一个函数,每次请求完成就设置一次。

640?wx_fmt=jpeg

  1. def \_\_set\_\_VIEWSTATE(self, soup):
  2. \_\_VIEWSTATE\_tag = soup.find('input', attrs={'name': '\_\_VIEWSTATE'})
  3. self.\_\_base\_data['\_\_VIEWSTATE'] = \_\_VIEWSTATE\_tag['value']

而其他数据,我们通过搜索响应网页就可以知道他们是干什么用的,这里我只说明我们要用的数据。

TextBox1为搜索框数据,我们可以用这个来搜索课程,dpkcmcGrid:txtPageSize为一页显示多少数据,经过测试,服务器最多响应200条。

值得注意的是ddl_xqbs这个校区数据信息,我所在的校区的数字代号为2,也许不同学校设置有所不同,需要自己设置一下,也可以从网页中获取

下面是基础数据包,由于我们搜索课程与选择课程都要使用这个基础数据包,所以我们直接在init函数里面新增

  1. self.\_\_base\_data = {
  2. '\_\_EVENTTARGET': '',
  3. '\_\_EVENTARGUMENT': '',
  4. '\_\_VIEWSTATE': '',
  5. 'ddl\_kcxz': '',
  6. 'ddl\_ywyl': '',
  7. 'ddl\_kcgs': '',
  8. 'ddl\_xqbs': '2',
  9. 'ddl\_sksj': '',
  10. 'TextBox1': '',
  11. 'dpkcmcGrid:txtChoosePage': '1',
  12. 'dpkcmcGrid:txtPageSize': '200',
  13. }

然后我们关注一下这条数据,我们搜索一下,发现这是课程的提交选课的代码,所以我们也可以直接从网页中获取,而on表示选项被选上

640?wx_fmt=jpeg

  1. kcmcGrid:\_ctl2:xk:'on'

搜索课程

课程有很多信息,比如名字,上课时间,地点,这些东西确定好了才知道选的是哪门课,所以我们先新建一个类来存储信息

  1. class Lesson:
  2. def \_\_init\_\_(self, name, code, teacher\_name, Time, number):
  3. self.name = name
  4. self.code = code
  5. self.teacher\_name = teacher\_name
  6. self.time = Time
  7. self.number = number
  8. def show(self):
  9. print('name:' + self.name + 'code:' + self.code + 'teacher\_name:' + self.teacher\_name + 'time:' + self.time)

有了这个类,我们就可以进行搜索课程了,具体代码看下面代码,解析网页内容就不细讲了。

  1. def \_\_search\_lessons(self, lesson\_name=''):
  2. self.\_\_base\_data['TextBox1'] = lesson\_name.encode('gb2312')
  3. request = requests.post(self.\_\_headers['Referer'], data=self.\_\_base\_data, headers=self.\_\_headers)
  4. soup = BeautifulSoup(request.text, 'lxml')
  5. self.\_\_set\_\_VIEWSTATE(soup)
  6. return self.\_\_get\_lessons(soup)
  7. def \_\_get\_lessons(self, soup):
  8. lesson\_list = []
  9. lessons\_tag = soup.find('table', id='kcmcGrid')
  10. lesson\_tag\_list = lessons\_tag.find\_all('tr')[1:]
  11. for lesson\_tag in lesson\_tag\_list:
  12. td\_list = lesson\_tag.find\_all('td')
  13. code = td\_list[0].input['name']
  14. name = td\_list[1].string
  15. teacher\_name = td\_list[3].string
  16. Time = td\_list[4]['title']
  17. number = td\_list[10].string
  18. lesson = self.Lesson(name, code, teacher\_name, Time, number)
  19. lesson\_list.append(lesson)
  20. return lesson\_list

进行选课

选课我们只要将lesson_list传入即可,这就是我们之前创建的Lesson类的实例的列表,‘Button’的内容为’ 提交 ',这两边各有一个空格,完事后我们可以进行发送请求进行选课。

这里我们用正则提取了错误信息,比如选课时间未到、上课时间冲突这些错误信息来提示用户,我们还解析了网页的已选课程,这里也不细讲了,都是基础的网页解析。

  1. def \_\_select\_lesson(self, lesson\_list):
  2. data = copy.deepcopy(self.\_\_base\_data)
  3. data['Button1'] = '  提交  '.encode('gb2312')
  4. for lesson in lesson\_list:
  5. code = lesson.code
  6. data[code] = 'on'
  7. request = requests.post(self.\_\_headers['Referer'], data=data, headers=self.\_\_headers)
  8. soup = BeautifulSoup(request.text, 'lxml')
  9. self.\_\_set\_\_VIEWSTATE(soup)
  10. error\_tag = soup.html.head.script
  11. if not error\_tag is None:
  12. error\_tag\_text = error\_tag.string
  13. r = "alert\('(.+?)'\);"

(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值