[Python]通过温州大学内网门户登录教务系统

本文介绍了使用Python进行网络爬虫的实践,详细讲解了如何登录内网门户并获取教务系统的课表信息。通过des加密方式处理密码,使用requests库进行HTTP请求,BeautifulSoup解析网页内容。主要步骤包括:登录内网门户、获取学生姓名、访问教务系统、解析公选课信息。
摘要由CSDN通过智能技术生成

项目地址:https://github.com/Jakesoso/WZU_helper

早就听说python在抓取数据方面功能的强大,现手上有一个现成的抓取对象,于是就趁着这个机会学习一下python。

毕竟还没接触过,所以在写的过程中借鉴了一部分代码。限于时间和技术,目前代码只实现了 登录内网门户 登录教务系统 抓取个人课表信息 抓取公选课信息 这几个功能。

运行环境:python3 校园网

import binascii
import re
import requests
from pyDes import ECB, PAD_PKCS5, des
from bs4 import BeautifulSoup

实现原理:

1) 登录内网门户:登录时密码有加密操作,具体思路:参考思路 。这边不赘述,放实现代码。 

        1.1) login_hall(username, password):        


# 登录内网门户
def login_hall(username, password):
    session = requests.session()

    session.headers = headers

    # 访问网址,返回包含认证页面链接的内容(自动跳转)
    url = 'https://source.wzu.edu.cn/login'
    resp = session.get(url, verify=False)

    # 提取认证链接并访问,经历一次重定向得到认证页面,且会返回一个cookie值:session
    croypto = re.search(r'"login-croypto">(.*?)<', resp.text, re.S).group(1)
    execution = re.search(r'"login-page-flowkey">(.*?)<', resp.text, re.S).group(1)

    # 构建post数据 填入自己的学号 密码
    data = {
        'username': username,  # 学号
        'type': 'UsernamePassword',
        '_eventId': 'submit',
        'geolocation': '',
        'execution': execution,
        'captcha_code': '',
        'croypto': croypto,  # 密钥 base64格式
        'password': encrypt(password, croypto)  # 密码 经过des加密 base64格式
    }

    # 提交cookie,进行登录(重定向)
    session.cookies.update({'isPortal': 'false'})
    url = 'https://source.wzu.edu.cn/login'
    resp = session.post(url, data=data)

    # 打印提示
    if resp.status_code == 200:
        print('成功登录内网门户大厅,请输入数字以继续操作!')
        print('1)教务系统')
    else:
        print('登录失败!检查账号密码,在校园网环境下登录')

    # 传出session
    return session

        1.2)des_encrypt(s, key) 和 def encrypt(pd, key) 解密函数

# des解密
def des_encrypt(s, key):
    """
    DES 加密
    :param key: 秘钥
    :param s: 原始字符串
    :return: 加密后字符串,16进制
    """
    secret_key = key
    k = des(secret_key, mode=ECB, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return en  # 得到加密后的16位进制密码 <class 'bytes'>


def encrypt(pd, key):
    """
    密码加密过程:
    1 从认证页面中可获得base64格式的秘钥
    2 将秘钥解码成bytes格式
    3 输入明文密码
    4 通过des加密明文密码
    5 返回base64编码格式的加密后密码
    :param pd: 明文密码
    :param key: 秘钥
    :return: 加密后的密码(base64格式)
    """
    key = binascii.a2b_base64(key.encode('utf-8'))  # 先解码 <class 'bytes'>
    pd_bytes = des_encrypt(pd, key)  # 得到加密后的16位进制密码 <class 'bytes'>
    pd_base64 = binascii.b2a_base64(pd_bytes, newline=False).decode('utf-8')
    return pd_base64

至此,我们成功进入了内网门户,可以进一步登录教务系统。

2) 登录教务系统

        2.1) 通过对内网门户的观察,得到教务系统的链接。这边直接进入,代码如下:

    url = 'http://hall.wzu.edu.cn/visit/dab247c354d64695a1ae6ad714011fa6'
    resp = session.get(url)

        2.2) 除此之外,我们还需要获取学生姓名,后面会用到,具体代码如下:

    # 获取姓名
    name = (re.search(r'"xhxm">(.*?)同学', resp.text, re.S).group(1))

至此,登陆操作完成,全部代码如下:

# 登录教务系统
def login_zhengfang(session):
    url = 'http://hall.wzu.edu.cn/visit/dab247c354d64695a1ae6ad714011fa6'
    resp = session.get(url)

    # 获取姓名
    name = (re.search(r'"xhxm">(.*?)同学', resp.text, re.S).group(1))

    # 打印提示
    if resp.status_code == 200:
        print(name + '同学你好' + ',请输入数字以继续操作!')

    else:
        print('登录失败,请重试!')

3) 公选课查询

        3.1) 通过对教务系统的观察,得到公选课界面的链接。

url = 'http://jwc3.wzu.edu.cn/xf_xsqxxxk.aspx?' + 'xh=' + str(username) + '&gnmkdm=N121112'

        3.2)访问公选课界面,通过模拟选课,找到发送的数据,具体如下:

data = {
    '__EVENTTARGET': '',
    '__EVENTARGUMENT': '',
    '__VIEWSTATE': viewstate,
    '__VIEWSTATEGENERATOR': '03DFB912',
    'ddl_kcxz': '',
    'ddl_ywyl': '',                                  # 有无余量
    'ddl_kcgs': '',                                  # 课程归属
    'ddl_xqbs': 1,                                   # 校区信息
    'ddl_sksj': '',
    'TextBox1': '',                                  # 课程搜索
    'dpkcmcGrid:txtChoosePage': '1',                 # 页数
    'dpkcmcGrid:txtPageSize': '15',                  # 每页元素个数

这里,我们需要得到  '__VIEWSTATE' 这一数据的值,我们可以通过get抓取到,代码如下:

resp = session.get(url)

# 获取viewstate
viewstate = re.search(r'name="__VIEWSTATE" value="(.*?)" />', resp.text, re.S).group(1)

        3.3)获取公选课信息,通过发送数据,得到返回结果并进行解析。这里不赘述,代码如下:

resp = session.post(url, data=data)

soup = BeautifulSoup(resp.text, 'html.parser')
html_selected = str(soup.findAll('table', id='DataGrid2'))  # 已选科目
html_all = str(soup.findAll('table', id='kcmcGrid'))
html_all = re.findall(r'top=60\'\)">(.*?)</a>', html_all, re.S)

至此,公选课信息获取完毕,补上输出方法,全部代码如下:

# 获取公选课信息
def zhengfang_enroll_course(name):
    url = 'http://jwc3.wzu.edu.cn/xf_xsqxxxk.aspx?' + 'xh=' + str(username) + '&gnmkdm=N121112'
   
    resp = session.get(url)

    # 校区信息(北校区 学院路校区 南校区 温州医科大学 在线学习)
    ddl_xqbs = '1'

    # 构建post数据,获取符合当前条件的选课
    viewstate = re.search(r'name="__VIEWSTATE" value="(.*?)" />', resp.text, re.S).group(1)
    data = {
        '__EVENTTARGET': '',
        '__EVENTARGUMENT': '',
        '__VIEWSTATE': viewstate,
        '__VIEWSTATEGENERATOR': '03DFB912',
        'ddl_kcxz': '',
        'ddl_ywyl': '',  # 有无余量
        'ddl_kcgs': '',  # 课程归属
        'ddl_xqbs': ddl_xqbs,  # 校区信息
        'ddl_sksj': '',
        'TextBox1': '',
        'dpkcmcGrid:txtChoosePage': '1',
        'dpkcmcGrid:txtPageSize': '200',
    }

    # 获取选课科目
    resp = session.post(url, data=data)

    soup = BeautifulSoup(resp.text, 'html.parser')
    html_selected = str(soup.findAll('table', id='DataGrid2'))  # 已选科目
    html_all = str(soup.findAll('table', id='kcmcGrid'))
    html_all = re.findall(r'top=60\'\)">(.*?)</a>', html_all, re.S)

    # 输出所有选课结果
    print('【科目   老师】')
    count = 0
    num = 1
    for each in html_all:
        count += 1
        if (count % 2 != 0):
            print(num, each, end=' ')
        if (count % 2 == 0):
            print(each, end='\n')
            num += 1

 还需说明一点,目前只支持查询,选课操作日后补充。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值