Python 3 学习笔记—《优雅的从教务系统中查成绩》

0x00 写在前面

每次查成绩都需要从学校官网查,这似乎有点累,何不写个代码,自动获取成绩。(以下是实现效果)

成绩
校务系统

0x01 准备工作

工具 [Chrome内核浏览器]或[IE8以上浏览器]、编程工具:python 3(可根据个人喜好来选择编程工具,这里我拿python来做演示,python3与python2有代码上的区别,注意区分。)

  • 使用IE、或者chrome浏览器进入教务系统对网页进行抓包。
    首先是 登录

login
登录所需条件:用户名、密码、验证码、登录类型、登录按钮

  • 以Chrome内核浏览器为例操作步骤

按下 F12 > Network 拦截 红色按钮表示开启拦截日志
log
选中Preserve log 就是防止页面跳转的时候 拦截的日志信息被清理掉

  • 准备工作做好以后 分别输入内容 user pwd code ,点击登录。

在这里插入图片描述
提示
页面会提示验证码不正确(当然我没有输入正确的验证码)
在这里插入图片描述
在这里插入图片描述

  • 登录的头信息包含(整体、响应头、请求头、提交表单)具体各个名词是什么意思,可以参考文章HTTP协议详解

首先提取出需要的数据信息。如以下
Request URL: http://119.145.248.32:81/default2.aspx
Request Method: POST
Cookie: ASP.NET_SessionId=tkppurvel0i0szru54px5145
Form_data:
__VIEWSTATE: dDw3OTkxMjIwNTU7Oz7/99NZP1opAgc5jOaeBNNUdogk9Q==
__VIEWSTATEGENERATOR: 92719903
TextBox1: user
TextBox2: pws
TextBox3: code
RadioButtonList1: %D1%A7%C9%FA
Button1:
然后我们要知道Form_data里各个数据代表什么,以及怎么获取

名称获取途径备注
VIEWSTATE右键 查看网页源代码 >Ctrl+F >搜索VIEWSTATE__VIEWSTATE value="dDw3OTkxMjIwNTU7Oz7/99NZP1opAgc5jOaeBNNUdogk9Q==
__VIEWSTATEGENERATOR同上__VIEWSTATEGENERATOR value=“92719903”
TextBox1用户输入的账号信息账号
TextBox2用户输入的密码内容密码
TextBox3用户输入的验证码内容验证码
RadioButtonList1URL编码登录的类型:部门、教师、学生、访客,都是固定值。这里是使用了gb2312>url编码
Button1无实际值登录按钮

URL编码在线加解码 http://tool.chinaz.com/tools/urlencode.aspx

http://119.145.248.32:81/CheckCode.aspx 验证码数据

接下来是 查询功能 点击学习成绩查询

成绩查询
记录下拦截信息在这里插入图片描述
查询
点击查询已修课程,可以查到所有成绩
这个也是POST在这里插入图片描述

  • __VIEWSTATE 这个名词有点眼熟,不过里的内容是一堆乱码内容其实是一个Base64编码,具体是什么内容我们不用关心,最重要是如何获取。
    我们在登录的时候也有提交过这个信息,所以也可以从网页源代码中获得。
名称获取途径备注
VIEWSTATE右键 查看网页源代码 >Ctrl+F >搜索VIEWSTATE__VIEWSTATE value="dDwtMTg3MzYzMTY5MDt0PHA8bDx4a…
__VIEWSTATEGENERATOR同上__VIEWSTATEGENERATOR value=“DB0F94E3”
ddlXN无实际值账号
ddlXQ无实际值密码
Button6URL编码:点击的按钮标题:查询已修课程最高成绩

整个流程大致就这样,也分析完了,接下来就是如何使用编程工具来实现。

0x02 功能的实现

python3 代码

# !/usr/bin/python
# encoding:utf-8
import lxml
import requests
from bs4 import BeautifulSoup
from http import cookiejar
from urllib.parse import quote

# getlist 获取网页中列表内容
def getlist(soup):
    trs = soup.find_all('tr')
    str = ""
    for link in trs:
        for td in link:
            if td.string != '\n':
                str = str+"|"+td.string
        str = str+"\n"
    print(str)
# getstate 获取网页源代码值
def getstate(soup):
    list_value = []
    for link in soup.find_all('input'):
        list_value.append(link.get('value'))
    VIEWSTATE = list_value[0]
    VIEWSTATEGENERATOR = list_value[1]
    return VIEWSTATE, VIEWSTATEGENERATOR


session = requests.session()
session.cookies = cookiejar.LWPCookieJar(filename='cookies')
# =====初始化自动管理Cookie

# gethtml 获取网页源代码
def gethtml(url):
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.8',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',
    }
    html = session.get(url, headers=headers)
    session.cookies.save()
    return html


##################正文############################
url = 'http://119.145.248.32:81/'  # 初始化登录界面 目的获取 VIEWSTATE和VIEWSTATEGENERATOR
soup = BeautifulSoup(gethtml(url).text, 'lxml')  # 创建 beautifulsoup 对象
VIEWSTATE, VIEWSTATEGENERATOR = getstate(soup)
# =====初始化 VIEWSTATE和VIEWSTATEGENERATOR

PostUrl = 'http://119.145.248.32:81/default2.aspx'  # 登录地址
CodeUrl = 'http://119.145.248.32:81/CheckCode.aspx'  # 验证码地址
# =====初始化登录post地址、验证码地址

picture = gethtml(CodeUrl).content  # 获取验证码数据
local = open('./CodeImg.jpg', 'wb')  # 将验证码保存到本地
local.write(picture)  # 写出验证码
local.close()  # 记得要关闭
# =========将验证码保存到本地
userid = input('请输入账号: ')  # 提示输入并保存到userid里
pwd = input('请输入密码: ')
VerifiedCode = input('输入验证码: ')
# =========提示用户输入内容
From_Data = {
    '__VIEWSTATE': VIEWSTATE,
    '__VIEWSTATEGENERATOR': VIEWSTATEGENERATOR,
    'TextBox1': userid,
    'TextBox2': pwd,
    'TextBox3': VerifiedCode,
    'RadioButtonList1': '学生',
    'Button1': '',
}
# =========保存表单
r = session.post(PostUrl, data=From_Data)  # 使用post类型提交表单给服务器
soup = BeautifulSoup(r.text, 'lxml')
# ======获取网页返回内容
name = soup.span.string  # 获取登录成功后的名字
name = name.replace('同学', '')  # 替换掉同学两个字
name_urlde = quote(name.encode('gbk'))  # 使用名字转为gbk再进行url编码
# =====URL编码姓名
# 判断是否登录成功
if name != '新生学籍信息查询系统':
    print("欢迎您:"+name)  # 登录成功后 提示信息
    url = "http://119.145.248.32:81/xscj_gc.aspx?xh=" + \
        userid+"&xm="+name_urlde+"&gnmkdm=N121605"  # 设置查询地址
    headers = {  # 设置 头信息 如果没设置 可能会获取失败
        'Referer': "http://119.145.248.32:81/xs_main.aspx?xh="+userid,
    }
    # 目的是获取 VIEWSTATE, VIEWSTATEGENERATOR
    html = session.get(url, headers=headers).text
    soup = BeautifulSoup(html, 'lxml')  # 创建 beautifulsoup 对象
    VIEWSTATE, VIEWSTATEGENERATOR = getstate(soup) # 取出源代码里的VIEWSTATE, VIEWSTATEGENERATOR
    #==========设置提交表单
    From_Data = {
        '__VIEWSTATE': VIEWSTATE,
        '__VIEWSTATEGENERATOR': VIEWSTATEGENERATOR,
        'ddlXN': '',
        'ddlXQ': '',
        'Button6': '%B2%E9%D1%AF%D2%D1%D0%DE%BF%CE%B3%CC%D7%EE%B8%DF%B3%C9%BC%A8',
    }
    r = session.post(url, headers=headers, data=From_Data) #使用post类型进行提交表单
    soup = BeautifulSoup(r.text, 'lxml')#取出提交信息后的内容
    getlist(soup)# 获取成绩列表并展示出来
else:
    print("您输入的账号或者验证码有误。请重新尝试!")
 

刚安装python的童鞋需要安装以下库,命令如下

pip install lxml
pip install requests
pip install BeautifulSoup
pip install cookiejar

运行结果

运行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值