0x2a

Don't Panic.

Steve's avatar Steve

Python实现广州大学教务系统模拟登陆

前言

继上次写了图书馆进馆人数爬虫后, 就琢磨着如何模拟登陆学校的门户和教务系统.

谷歌上有很多关于正方教务系统模拟登陆的教程, 一般思路是通过正方系统的某个页面(如default2.aspx , default_ysdx.aspx 等)获得不用输入验证码的登陆页面. 然后post以下数据以实现模拟登陆

12-13-zfpost.png

但是广州大学的教务系统是和学生门户网站关联的,不是常规的正方教务系统登陆页面. 当然, 也可以找到类似页面:

12-13-yslogin.png

但是实验发现无法使用学生账号及密码登陆, 大概是因为学校对密码做了一定的加密.

没办法只能另找方法.

分析页面

在这个页面查看源码后可以发现

12-13-source.png

简单试了一下之后发现202.192.18.18x(x = 2,3,4,5,9) 都是可以到达登陆页面的

本文在202.192.18.184 进行实验

利用 Fiddler 软件进行抓包. 获得以下结果

12-13-fiddler1.png

对第一个结果进行分析:

12-13fiddler2.png

可以看出username 是我们的学号, password是门户密码, 那下面的那些参数分别是什么呢?我们来回到登陆页面源码:

12-13-source2.png

原来 lt execution两个值是每次加载页面都会改变的, 我们需要从源码里面获取这两个值作为参数.

利用 Python 的 BeautifulSoup 可以简单获取 lt, execution 两个值 :

def get_webflow(url):
    response = self.session.get(url = url,headers = self.headers)
    soup = BeautifulSoup(response.text,'html.parser')
    lt = soup.find('input',{'name' : 'lt'})['value']#获取lt值
    execution = soup.find('input',{'name' : 'execution'})['value']#获取execution值
    soup.clear()#清除没有必要的缓存
    return(lt,execution)

然后就可以利用获得的数值去构建post的内容了:

    lt, execution = get_webflow(url)
    postdata = {
        'username' : account,
        'password' : passwd,
        'lt' : lt,
        'execution' : execution,
        '_eventId' : 'submit',
        'submit' : '登录'
    }

然后利用 Python 的 requests 库就可以发送带有 session 的 post 了

这样模拟登陆之后我们就可以直接访问我们的目标页面了.

12-13-login.png

看到这个喜闻乐见的页面就代表我们登陆成功啦

Python3 代码

一下是完整代码:

import requests
from bs4 import BeautifulSoup
import getpass #这个库可以让我们输密码的时候不展现在屏幕上

class login_gzdx(object):
    def __init__(self,headers):
        self.session = requests.session()
        self.headers = headers
        self.url = 'https://cas.gzhu.edu.cn/cas_server/login?service=http%3a%2f%2f202.192.18.184%2fLogin_gzdx.aspx'

    def login(self, account, passwd):
      '''利用session及post登录门户
          且利用session直达教务网站'''
        self.username = account
        self.password = passwd
        lt, execution = self.get_webflow()
        postdata = {
            'username' : account,
            'password' : passwd,
            'lt' : lt,
            'execution' : execution,
            '_eventId' : 'submit',
            'submit' : '登录'
        }

        response = self.session.post(url = self.url, headers = self.headers, data = postdata)
        if response.status_code == 200:
            print('成功')
            jwurl = 'http://202.192.18.184/xs_main.aspx?xh=' + account#跳转到教务网站的url
            #text = self.session.get('http://my.gzhu.edu.cn/',headers = headers)#此注释是登陆门户
            text = self.session.get(jwurl,headers = headers)
            print(text.text)
        else:
            print(response.text)
    def get_webflow(self):
      '''利用Beautiful获得lt 及 executions的值'''
        response = self.session.get(url = self.url,headers = self.headers)
        soup = BeautifulSoup(response.text,'html.parser')
        lt = soup.find('input',{'name' : 'lt'})['value']#获取lt值
        execution = soup.find('input',{'name' : 'execution'})['value']#获取execution值
        soup.clear()
        return(lt,execution)

if __name__ == '__main__':
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36",
    }
    jw = login_gzdx(headers = headers)
    account = input('输出学号')
    password = getpass.getpass("请输入您的密码:")
    jw.login(account = account,passwd =password)

P.S. 做到一大半才发现学校门户的模拟登陆和 CSDN 基本是一样的…参考了一下此源码 (代码能力实在差远了)

TODO list:

  1. 获得课程表
  2. 获得学科成绩
  3. 自动抢课