基于tkinter界面requests爬虫实现的学生事务管理平台自动填写系统

简 介:此系统针对全球某工商每学期都要学生填写的学生互评,于可视化界面进行一键填写操作。
关键词:python, tikinter,gui,requests,爬虫,桌面程序


前言

最近一直在学爬虫的scrapy框架,学得有些累了,想着可不可以做些比较有意思的事情。正好之前有个学长曾经写过学校的学生事务管理平台自动填写系统,所以打算将其优化一下,并通过Tkinter模块做出用户可视化界面。


一、实际效果

在这里插入图片描述在这里插入图片描述

分为一键满分评分与具体评分两种办法,适用于不同群体的需求。

二、使用步骤

1.引入库与全局变量

代码如下(示例):

from tkinter import *
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import tkinter.messagebox
page_index = 1

2.自动填写之post请求

代码如下(示例):


    # 第一级:学校登录界面结构不变,可直接抓包下一级网址,不需要进行数据解析,故不做处理
    requests.packages.urllib3.disable_warnings()  # 以防网站需要验证证书
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71'
    }
    session = requests.session()
    # 第二级:赋值参数负载,进行登录,目前验证码不进行校对,故可省略,并需存储登录cookie
    second_url = 'https://xssw.zjgsu.edu.cn/api/v1/login'

    data = {
        'password': ety_mm.get(),
        'unionid': 'null',
        'xgh': ety_zh.get(),
    }
    second_page_json = session.post(url=second_url, headers=headers, data=data).json()
    session.cookies['token'] = second_page_json['data']['access_token']
    # 第三级:对测评详情页面发起get请求,获得json响应,以供后面逐个提交请求
    third_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/getGroupList?set_id=180&type=1'
    third_page_json = session.get(url=third_url, headers=headers).json()

    fourth_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/group'
    student_amount = 0
    student_index = 0
    total_score = 0
    for it in third_page_json['data']:
        if CheckVar[student_index].get():
            if page_index == 1:
                Type = '品德素质'
            else:
                Type = '心理素质'

            if stu_name[student_index].split('已完成测评')[0] == Type:
                print(it['xm'] + stu_name[student_index])
            else:
                in_data = {"option1": int(ety_pj1.get()), "option2": int(ety_pj2.get()), "option3": int(ety_pj3.get()),
                           "option4": int(ety_pj4.get()), "option5": int(ety_pj5.get()), "set_id": "121",
                           "type": page_index,
                           "xgh": it['xgh']}
                session.post(url=fourth_url, headers=headers, json=in_data).json()

                total_score = int(ety_pj1.get()) + int(ety_pj2.get()) + int(ety_pj3.get()) + int(ety_pj4.get()) + int(
                    ety_pj5.get())

                Lstbox.insert('end',
                               '学生{}:{}  {}  评分为:{} 完成测评!'.format(student_amount + 1, it['xm'], Type, total_score))
                stu_name[student_index] = Type + '已完成测评'
                student_amount += 1
        student_index += 1
    Lstbox.insert('end','你对每位学生的评分为{}  共{}位学生测评成功!'.format(total_score, student_amount))
    lb_error.configure(text='测评结束!')

tkinter这个模块自己也是突发奇想地想去学习的,所以算是一边学一边写,所以慢慢地写到后面发现自己写崩了,整个程序感觉就像是为了交互而交互,整体结构十分冗余。

这边是以“具体评分”的子函数为例的,“全部满分评分”与其基本相同。

3.Tkinter的可视化界面

if __name__ == '__main__':
    root = Tk()
    root.title('浙商大学生事务管理平台自动填写互评 by:小泽不偷懒')
    root.geometry('880x580')
    lb_zh = Label(root, text='学号:', font=('等线', 20), width=20, height=2)
    lb_zh.place(height=50, width=85, relx=0.2, rely=0.2)
    ety_zh = Entry()
    ety_zh.place(height=25, width=265, relx=0.3, rely=0.22)

    lb_mm = Label(root, text='密码:', font=('等线', 20), width=20, height=2)
    lb_mm.place(height=50, width=85, relx=0.2, rely=0.3)
    ety_mm = Entry(show='*')
    ety_mm.place(height=25, width=265, relx=0.3, rely=0.32)

    lb_error = Label(root, text='请输入学号与密码后进行操作!', font=('等线', 15), width=20, height=2, fg='red')
    lb_error.place(height=20, width=280, relx=0.31, rely=0.38)

    btn_pf1 = Button(root, text='具体评分', font='等线', relief=RAISED,
                     command=lambda: spider_1())
    btn_pf1.place(height=28, width=120, relx=0.62, rely=0.22)

    btn_pf2 = Button(root, text='全部满分评分', font='等线', relief=RAISED,
                     command=lambda: spider_2())
    btn_pf2.place(height=28, width=120, relx=0.62, rely=0.32)

    # 评分各小项

    lb_pj = Label(root, text='品德素质评价', font=('等线', 12), width=20, height=2)
    lb_pj.place(height=25, width=95, relx=0.79, rely=0.35)
    btn = Button(root, text='切换', font=('等线', 10), relief=RAISED, command=lambda: change_page(page_index))
    btn.place(height=23, width=39, relx=0.92, rely=0.35)

    lb_pj1 = Label(root, text='政治素养:', font=('等线', 10), width=20, height=2)
    lb_pj1.place(height=25, width=85, relx=0.78, rely=0.4)
    ety_pj1 = Entry()
    ety_pj1.place(height=15, width=35, relx=0.89, rely=0.409)
    ety_pj1.insert(0, '20')

    lb_pj2 = Label(root, text='法制观念:', font=('等线', 10), width=20, height=2)
    lb_pj2.place(height=25, width=85, relx=0.78, rely=0.44)
    ety_pj2 = Entry()
    ety_pj2.place(height=15, width=35, relx=0.89, rely=0.449)
    ety_pj2.insert(0, '20')

    lb_pj3 = Label(root, text='诚实守信:', font=('等线', 10), width=20, height=2)
    lb_pj3.place(height=25, width=85, relx=0.78, rely=0.48)
    ety_pj3 = Entry()
    ety_pj3.place(height=15, width=35, relx=0.89, rely=0.489)
    ety_pj3.insert(0, '20')

    lb_pj4 = Label(root, text='团队协作:', font=('等线', 10), width=20, height=2)
    lb_pj4.place(height=25, width=85, relx=0.78, rely=0.52)
    ety_pj4 = Entry()
    ety_pj4.place(height=15, width=35, relx=0.89, rely=0.529)
    ety_pj4.insert(0, '20')

    lb_pj5 = Label(root, text='社会责任:', font=('等线', 10), width=20, height=2)
    lb_pj5.place(height=25, width=85, relx=0.78, rely=0.56)
    ety_pj5 = Entry()
    ety_pj5.place(height=15, width=35, relx=0.89, rely=0.569)
    ety_pj5.insert(0, '20')

    root.mainloop()

def change_page(type):
    global page_index
    if type == 1:
        page_index = 2
        lb_pj.configure(text='心理素质评价')
        lb_pj1.configure(text='身体素质')
        lb_pj2.configure(text='乐观情绪')
        lb_pj3.configure(text='适应能力')
        lb_pj4.configure(text='自律能力')
        lb_pj5.configure(text='心理承受能力')

        ety_pj1.delete(0, 'end')
        ety_pj1.insert(0, '20')
        ety_pj2.delete(0, 'end')
        ety_pj2.insert(0, '20')
        ety_pj3.delete(0, 'end')
        ety_pj3.insert(0, '20')
        ety_pj4.delete(0, 'end')
        ety_pj4.insert(0, '20')
        ety_pj5.delete(0, 'end')
        ety_pj5.insert(0, '20')
    else:
        page_index = 1
        lb_pj.configure(text='品德素质评价')
        lb_pj1.configure(text='政治素养')
        lb_pj2.configure(text='法制观念')
        lb_pj3.configure(text='诚实守信')
        lb_pj4.configure(text='团队协作')
        lb_pj5.configure(text='社会责任')

        ety_pj1.delete(0, 'end')
        ety_pj1.insert(0, '20')
        ety_pj2.delete(0, 'end')
        ety_pj2.insert(0, '20')
        ety_pj3.delete(0, 'end')
        ety_pj3.insert(0, '20')
        ety_pj4.delete(0, 'end')
        ety_pj4.insert(0, '20')
        ety_pj5.delete(0, 'end')
        ety_pj5.insert(0, '20')
lb_error.configure(text='正在测评中...')

    winNew = Toplevel(root)
    winNew.geometry('480x940')
    winNew.title('评分信息')

    btStart = Button(winNew, text='继续填写', command=winNew.destroy)
    btStart.place(relx=0.01, rely=0.01)

    LstLable = Label(winNew, relief=RAISED, )
    LstLable.place(relx=0.3)
    Lstbox = Listbox(LstLable, width='45', height='40')
    Lstbox.pack()

三、完整的代码

# -*- coding: utf-8 -*- 
# @Time : 2022/8/4 22:31 
# @Author : 小泽不偷懒
# @File : tkinter之学生互评.py

from tkinter import *
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import tkinter.messagebox

page_index = 1

def change_page(type):
    global page_index
    if type == 1:
        page_index = 2
        lb_pj.configure(text='心理素质评价')
        lb_pj1.configure(text='身体素质')
        lb_pj2.configure(text='乐观情绪')
        lb_pj3.configure(text='适应能力')
        lb_pj4.configure(text='自律能力')
        lb_pj5.configure(text='心理承受能力')

        ety_pj1.delete(0, 'end')
        ety_pj1.insert(0, '20')
        ety_pj2.delete(0, 'end')
        ety_pj2.insert(0, '20')
        ety_pj3.delete(0, 'end')
        ety_pj3.insert(0, '20')
        ety_pj4.delete(0, 'end')
        ety_pj4.insert(0, '20')
        ety_pj5.delete(0, 'end')
        ety_pj5.insert(0, '20')
    else:
        page_index = 1
        lb_pj.configure(text='品德素质评价')
        lb_pj1.configure(text='政治素养')
        lb_pj2.configure(text='法制观念')
        lb_pj3.configure(text='诚实守信')
        lb_pj4.configure(text='团队协作')
        lb_pj5.configure(text='社会责任')

        ety_pj1.delete(0, 'end')
        ety_pj1.insert(0, '20')
        ety_pj2.delete(0, 'end')
        ety_pj2.insert(0, '20')
        ety_pj3.delete(0, 'end')
        ety_pj3.insert(0, '20')
        ety_pj4.delete(0, 'end')
        ety_pj4.insert(0, '20')
        ety_pj5.delete(0, 'end')
        ety_pj5.insert(0, '20')


def spider_1():
    # 第一级:学校登录界面结构不变,可直接抓包下一级网址,不需要进行数据解析,故不做处理
    requests.packages.urllib3.disable_warnings()  # 以防网站需要验证证书
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71'
    }
    url = 'https://xssw.zjgsu.edu.cn/#/login'
    session = requests.session()
    # 第二级:赋值参数负载,进行登录,目前验证码不进行校对,故可省略,并需存储登录cookie
    second_url = 'https://xssw.zjgsu.edu.cn/api/v1/login'

    data = {
        'password': ety_mm.get(),
        'unionid': 'null',
        'xgh': ety_zh.get(),
    }
    second_page_json = session.post(url=second_url, headers=headers, data=data).json()
    if second_page_json['errorCode'] == 40101:
        tkinter.messagebox.showerror('登录失败', '你的账号或密码输入错误!')
        return
    else:
        tkinter.messagebox.showinfo('登录成功', '登录成功!!')

    session.cookies['token'] = second_page_json['data']['access_token']
    # 第三级:对测评详情页面发起get请求,获得json响应,以供后面逐个提交请求
    third_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/getGroupList?set_id=180&type=1'
    third_page_json = session.get(url=third_url, headers=headers).json()

    # 第四级:对每个学生进行post测评请求
    # -测试是否在测评时间内
    in_data = {"option1": 1, "option2": 1, "option3": 1,
               "option4": 1, "option5": 1, "set_id": "121",
               "type": 1,
               "xgh": 'xxx'}
    fourth_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/group'
    fourth_url_json = session.post(url=fourth_url, headers=headers, json=in_data).json()
    if fourth_url_json['message'] == '不在开放时间内':
        lb_error.configure(text='当前时间不在开放时间段内!')
    # -获取数据并发送请求,并生成复选框
    CheckVar = []
    stu = []
    stu_name = []
    student_amount = 0
    stu_xy = 0
    for it in third_page_json['data']:
        stu_xy += 1
        CheckVar.append(IntVar())
        CheckVar[student_amount].set(1)
        stu_name.append(it['xm'])
        stu.append(Checkbutton(root, text=it['xm'], variable=CheckVar[student_amount]))
        stu[student_amount].place(height=20, width=65, relx=0.01 + (stu_xy - 1) // 5 * 0.1,
                                  rely=0.45 + (stu_xy - 1) % 5 * 0.1)
        student_amount += 1
    btn_pf2 = Button(root, text='开始评分', font='等线', relief=RAISED,
                     command=lambda: spider_3(CheckVar, stu_name))
    btn_pf2.place(height=28, width=120, relx=0.8, rely=0.68)


def spider_2():
    lb_error.configure(text='正在测评中...')

    winNew = Toplevel(root)
    winNew.geometry('480x940')
    winNew.title('评分信息')

    btStart = Button(winNew, text='继续填写', command=winNew.destroy)
    btStart.place(relx=0.01, rely=0.01)

    LstLable = Label(winNew, relief=RAISED, )
    LstLable.place(relx=0.3)
    Lstbox = Listbox(LstLable, width='45', height='40')
    Lstbox.pack()
    requests.packages.urllib3.disable_warnings()  # 以防网站需要验证证书
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71'
    }
    session = requests.session()
    second_url = 'https://xssw.zjgsu.edu.cn/api/v1/login'

    data = {
        'password': ety_mm.get(),
        'unionid': 'null',
        'xgh': ety_zh.get(),
    }
    second_page_json = session.post(url=second_url, headers=headers, data=data).json()
    if second_page_json['errorCode'] == 40101:
        tkinter.messagebox.showerror('登录失败', '你的账号或密码输入错误!')
        return
    else:
        tkinter.messagebox.showinfo('登录成功', '登录成功!!')

    session.cookies['token'] = second_page_json['data']['access_token']
    third_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/getGroupList?set_id=180&type=1'
    third_page_json = session.get(url=third_url, headers=headers).json()
    in_data = {"option1": 1, "option2": 1, "option3": 1,
               "option4": 1, "option5": 1, "set_id": "121",
               "type": 1,
               "xgh": 'xxx'}
    fourth_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/group'
    fourth_url_json = session.post(url=fourth_url, headers=headers, json=in_data).json()
    if fourth_url_json['message'] == '不在开放时间内':
        lb_error.configure(text='当前时间不在开放时间段内!')

    student_amount = 0
    for it in third_page_json['data']:

        for i in [1, 2]:
            in_data = {"option1": 20, "option2": 20, "option3": 20,
                       "option4": 20, "option5": 20, "set_id": "121",
                       "type": i,
                       "xgh": it['xgh']}
            session.post(url=fourth_url, headers=headers, json=in_data).json()
            if i == 1:
                Type = '品德素质'
            else:
                Type = '心理素质'
            Lstbox.insert('end','学生{}:{}  {}  评分为:100 完成测评!'.format(student_amount + 1, it['xm'], Type))
        student_amount += 1
    Lstbox.insert('end','你对每位学生的评分为{}  共{}位学生测评成功!'.format(100, student_amount))
    lb_error.configure(text='测评结束!')

def spider_3(CheckVar, stu_name):
    lb_error.configure(text='正在测评中...')
    winNew = Toplevel(root)
    winNew.geometry('480x940')
    winNew.title('评分信息')

    btStart = Button(winNew, text='继续填写', command=winNew.destroy)
    btStart.place(relx=0.01, rely=0.01)

    LstLable = Label(winNew, relief=RAISED, )
    LstLable.place(relx=0.3)
    Lstbox = Listbox(LstLable, width='45', height='40')
    Lstbox.pack()

    # 第一级:学校登录界面结构不变,可直接抓包下一级网址,不需要进行数据解析,故不做处理
    requests.packages.urllib3.disable_warnings()  # 以防网站需要验证证书
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71'
    }
    session = requests.session()
    # 第二级:赋值参数负载,进行登录,目前验证码不进行校对,故可省略,并需存储登录cookie
    second_url = 'https://xssw.zjgsu.edu.cn/api/v1/login'

    data = {
        'password': ety_mm.get(),
        'unionid': 'null',
        'xgh': ety_zh.get(),
    }
    second_page_json = session.post(url=second_url, headers=headers, data=data).json()
    session.cookies['token'] = second_page_json['data']['access_token']
    # 第三级:对测评详情页面发起get请求,获得json响应,以供后面逐个提交请求
    third_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/getGroupList?set_id=180&type=1'
    third_page_json = session.get(url=third_url, headers=headers).json()

    fourth_url = 'https://xssw.zjgsu.edu.cn/api/v1/home/complex/evaluate/group'
    student_amount = 0
    student_index = 0
    total_score = 0
    for it in third_page_json['data']:
        if CheckVar[student_index].get():
            if page_index == 1:
                Type = '品德素质'
            else:
                Type = '心理素质'

            if stu_name[student_index].split('已完成测评')[0] == Type:
                print(it['xm'] + stu_name[student_index])
            else:
                in_data = {"option1": int(ety_pj1.get()), "option2": int(ety_pj2.get()), "option3": int(ety_pj3.get()),
                           "option4": int(ety_pj4.get()), "option5": int(ety_pj5.get()), "set_id": "121",
                           "type": page_index,
                           "xgh": it['xgh']}
                session.post(url=fourth_url, headers=headers, json=in_data).json()

                total_score = int(ety_pj1.get()) + int(ety_pj2.get()) + int(ety_pj3.get()) + int(ety_pj4.get()) + int(
                    ety_pj5.get())

                Lstbox.insert('end',
                               '学生{}:{}  {}  评分为:{} 完成测评!'.format(student_amount + 1, it['xm'], Type, total_score))
                stu_name[student_index] = Type + '已完成测评'
                student_amount += 1
        student_index += 1
    Lstbox.insert('end','你对每位学生的评分为{}  共{}位学生测评成功!'.format(total_score, student_amount))
    lb_error.configure(text='测评结束!')

if __name__ == '__main__':
    root = Tk()
    root.title('浙商大学生事务管理平台自动填写互评 by:小泽不偷懒')
    root.geometry('880x580')
    lb_zh = Label(root, text='学号:', font=('等线', 20), width=20, height=2)
    lb_zh.place(height=50, width=85, relx=0.2, rely=0.2)
    ety_zh = Entry()
    ety_zh.place(height=25, width=265, relx=0.3, rely=0.22)

    lb_mm = Label(root, text='密码:', font=('等线', 20), width=20, height=2)
    lb_mm.place(height=50, width=85, relx=0.2, rely=0.3)
    ety_mm = Entry(show='*')
    ety_mm.place(height=25, width=265, relx=0.3, rely=0.32)

    lb_error = Label(root, text='请输入学号与密码后进行操作!', font=('等线', 15), width=20, height=2, fg='red')
    lb_error.place(height=20, width=280, relx=0.31, rely=0.38)

    btn_pf1 = Button(root, text='具体评分', font='等线', relief=RAISED,
                     command=lambda: spider_1())
    btn_pf1.place(height=28, width=120, relx=0.62, rely=0.22)

    btn_pf2 = Button(root, text='全部满分评分', font='等线', relief=RAISED,
                     command=lambda: spider_2())
    btn_pf2.place(height=28, width=120, relx=0.62, rely=0.32)

    # 评分各小项

    lb_pj = Label(root, text='品德素质评价', font=('等线', 12), width=20, height=2)
    lb_pj.place(height=25, width=95, relx=0.79, rely=0.35)
    btn = Button(root, text='切换', font=('等线', 10), relief=RAISED, command=lambda: change_page(page_index))
    btn.place(height=23, width=39, relx=0.92, rely=0.35)

    lb_pj1 = Label(root, text='政治素养:', font=('等线', 10), width=20, height=2)
    lb_pj1.place(height=25, width=85, relx=0.78, rely=0.4)
    ety_pj1 = Entry()
    ety_pj1.place(height=15, width=35, relx=0.89, rely=0.409)
    ety_pj1.insert(0, '20')

    lb_pj2 = Label(root, text='法制观念:', font=('等线', 10), width=20, height=2)
    lb_pj2.place(height=25, width=85, relx=0.78, rely=0.44)
    ety_pj2 = Entry()
    ety_pj2.place(height=15, width=35, relx=0.89, rely=0.449)
    ety_pj2.insert(0, '20')

    lb_pj3 = Label(root, text='诚实守信:', font=('等线', 10), width=20, height=2)
    lb_pj3.place(height=25, width=85, relx=0.78, rely=0.48)
    ety_pj3 = Entry()
    ety_pj3.place(height=15, width=35, relx=0.89, rely=0.489)
    ety_pj3.insert(0, '20')

    lb_pj4 = Label(root, text='团队协作:', font=('等线', 10), width=20, height=2)
    lb_pj4.place(height=25, width=85, relx=0.78, rely=0.52)
    ety_pj4 = Entry()
    ety_pj4.place(height=15, width=35, relx=0.89, rely=0.529)
    ety_pj4.insert(0, '20')

    lb_pj5 = Label(root, text='社会责任:', font=('等线', 10), width=20, height=2)
    lb_pj5.place(height=25, width=85, relx=0.78, rely=0.56)
    ety_pj5 = Entry()
    ety_pj5.place(height=15, width=35, relx=0.89, rely=0.569)
    ety_pj5.insert(0, '20')

    root.mainloop()


总结

虽然程序和界面做的都还是挺粗糙的,整个底层逻辑可能看起来有点让人贻笑大方了。有点像是为了可视化而进行一些可视化操作。涉及到用户交互,其实还有很多地方和想法我都没有实现,主要是感觉差不多了哈哈哈。
不管怎么说最后的成品个人还算是比较满意的,自己也花了一点心思到用户交互体验上,说到这个用户交互真是想想就头疼,可能一个偏习惯化的行为你就得为此大改程序。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值