首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python3可视化爬取教务系统实现查询功能

Python3可视化爬取教务系统实现查询功能

作者头像
HcodeBlogger
发布2020-07-14 10:07:26
8780
发布2020-07-14 10:07:26
举报
文章被收录于专栏:Hcode网站Hcode网站Hcode网站

前言

今天来补充之前的界面操作系统,为学生查询操作系统2.0版本,依旧是用wxpython来做一个可视化的操作界面,用的工具依然是selenium库,beautifulsoup4库,还有设计界面的wx,和表格wx.grid,后面两个只要下载wxpython库即可

首先是界面操作

里面的分别对应的文本,按钮,背景图片,图标都有标明

#继承wx库里面的Frame类来使用
class myFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'ZSC-学生查询系统', pos=(100, 100), size=(1400, 600))
        self.MaxSize = self.Size
        self.MinSize = self.Size
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer1 = wx.BoxSizer(wx.VERTICAL)
        sizer3 = wx.BoxSizer(wx.VERTICAL)
        font = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)

        #设置窗口以及托盘图标
        icon = wx.Icon()
        icon.CopyFromBitmap(wx.Bitmap(wx.Image(("E:\py\系统图片\zsc.jpg"), wx.BITMAP_TYPE_JPEG)))
        self.SetIcon(icon)

        #设置左边背景学院logo
        image = wx.Image("E:\py\系统图片\中山学院.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        self.background = wx.StaticBitmap(panel, -1, bitmap=image,style=wx.ALIGN_CENTER)
        sizer1.Add(self.background,proportion=10,flag= wx.ALIGN_CENTER_VERTICAL, border=10)

        #设置静态‘用户名'
        self.text1 = wx.StaticText(panel, -1, '用户名:', style=wx.ALIGN_CENTER)
        self.text1.SetFont(font)
        sizer1.Add(self.text1, proportion=2, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #用户名输入框
        self.text2 = wx.TextCtrl(panel, -1, size=(200, -1), style=wx.TE_LEFT)
        self.text2.SetFont(font)
        sizer1.Add(self.text2, proportion=0, flag=wx.ALIGN_CENTER | wx.EXPAND, border=15)

        #设置静态'密码'
        self.text3 = wx.StaticText(panel, -1, '密码:', style=wx.ALIGN_CENTER)
        self.text3.SetFont(font)
        sizer1.Add(self.text3, proportion=2, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #密码输入框
        self.text4 = wx.TextCtrl(panel, -1, size=(200, -1), style=wx.TE_LEFT|wx.TE_PASSWORD|wx.TE_PROCESS_ENTER)
        self.text4.SetFont(font)
        sizer1.Add(self.text4, proportion=0, flag=wx.ALIGN_CENTER | wx.EXPAND, border=15)

        # 设置获取成绩按钮
        self.command1 = wx.Button(panel, -1, '→获取个人成绩单')
        self.command1.SetFont(font)
        self.command1.SetBackgroundColour('#3299CC')
        sizer1.Add(self.command1, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置获取课程表按钮
        self.command4 = wx.Button(panel, -1, '→获取个人课程表')
        self.command4.SetFont(font)
        self.command4.SetBackgroundColour('#DBDB70')
        sizer1.Add(self.command4, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置获取素拓分按钮
        self.command3 = wx.Button(panel, -1, '→获取个人素拓分')
        self.command3.SetFont(font)
        self.command3.SetBackgroundColour('#32CC32')
        sizer1.Add(self.command3, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置重置按钮
        self.command2 = wx.Button(panel, -1, '→重置输入框')
        self.command2.SetFont(font)
        self.command2.SetBackgroundColour((random.randint(1, 255), random.randint(0, 255), random.randint(0, 255)))
        sizer1.Add(self.command2, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置消息提示文本
        self.text5 = wx.StaticText(panel, -1, '\n\n', style=wx.ALIGN_CENTER)
        self.text5.SetFont(font)
        self.text5.SetForegroundColour('Red')
        sizer1.Add(self.text5, proportion=15, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #设置个人信息文本
        self.text6 = wx.StaticText(panel, -1, '姓名:')
        self.text7 = wx.StaticText(panel, -1, '学号:')
        self.text8 = wx.StaticText(panel, -1, '学院:')
        sizer1.Add(self.text6, proportion=3, flag=wx.LEFT, border=0)
        sizer1.Add(self.text7, proportion=3, flag=wx.LEFT, border=0)
        sizer1.Add(self.text8, proportion=3, flag=wx.LEFT, border=0)

        #把分布局全部加入整体顶级布局
        sizer.Add(sizer1, flag=wx.EXPAND | wx.ALL, border=20)
        sizer.Add(sizer3, flag=wx.EXPAND | wx.ALL, border=20)
        self.grid = mygrid(panel)
        sizer.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=25)

        self.grid.SetSize((200, 400))

        panel.SetSizer(sizer)

        #四个按钮对应的事件
        self.command1.Bind(wx.EVT_BUTTON, self.command1_event)
        self.command4.Bind(wx.EVT_BUTTON, self.command4_event)
        self.command3.Bind(wx.EVT_BUTTON, self.command3_event)
        self.command2.Bind(wx.EVT_BUTTON, self.command2_event)
        self.Show()

    def command1_event(self, event):
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()
        self.text5.SetLabel(u'\n温馨提示:\n' + '⚪登录信息验证中...')
        self.text5.Update()
        try:
            name = self.text2.GetValue()
            password = self.text4.GetValue()
            courses = get_data_from_zsc1(name,password)
            if courses.result == False:
                self.text5.SetLabel(u'\n温馨提示:\n' + '×用户名或密码错误!' )
            else:
                student_course = courses.my_score_list
                self.text5.SetLabel(u'\n温馨提示:\n' + '√登录成功并获得成绩!')
                self.text6.SetLabel('姓名:' + courses.my_information[0])
                self.text7.SetLabel('学号:' + courses.my_information[1])
                self.text8.SetLabel('学院:' + courses.my_information[2] )
                try:
                    self.grid.header = grade
                    for i in range(len(self.grid.header)):
                        self.grid.SetColLabelValue(i, self.grid.header[i])
                    self.grid.Update()
                    self.grid.Refresh()
                except:
                    pass
                n1 = len(student_course)
                n2 = len(student_course[0])
                self.grid.InsertRows(0, n1)
                for i in range(0, n1):
                    for j in range(0, n2):
                        self.grid.SetCellValue(i, j, student_course[i][j])
                #self.grid.AutoSize() #自动调整单元格大小
        except:
            self.Message = wx.MessageDialog(self, '账号或密码不能为空!', 'ERROR',wx.ICON_ERROR)
            self.Message.ShowModal()
            self.Message.Destroy()

    def command4_event(self, event):
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()
        self.text5.SetLabel(u'\n温馨提示:\n' + '⚪登录信息验证中...')
        self.text5.Update()
        try:
            name = self.text2.GetValue()
            password = self.text4.GetValue()
            courses = get_data_from_zsc2(name,password)
            if courses.result == False:
                self.text5.SetLabel(u'\n温馨提示:\n' + '×用户名或密码错误!' )
            else:
                student_timetable = courses.all_data
                self.text5.SetLabel(u'\n温馨提示:\n' + '√登录成功并获得课程表!')
                self.text6.SetLabel('姓名:' + courses.my_information[0])
                self.text7.SetLabel('学号:' + courses.my_information[1])
                self.text8.SetLabel('学院:' + courses.my_information[2] )
                try:
                    self.grid.header = timetable
                    for i in range(len(self.grid.header)):
                        self.grid.SetColLabelValue(i, self.grid.header[i])
                    self.grid.Update()
                    self.grid.Refresh()
                except:
                    pass
                n1 = len(student_timetable)
                n2 = len(student_timetable[0])
                self.grid.InsertRows(0, n1)
                for i in range(0, n1):
                    for j in range(0, n2):
                        self.grid.SetCellValue(i, j, student_timetable[i][j])
                self.grid.SetCellSize(6, 0, 1, 5) #合并单元格 合并第6行第1个为1x5的单元格
                #设置行的高度
                for i in range(0, n1):
                    self.grid.SetRowSize(i, 80)
                #设置列的宽度
                for j in range(0, n2):
                    self.grid.SetColSize(j, 120)
                #self.grid.AutoSize()
        except:
            self.Message = wx.MessageDialog(self, '账号或密码不能为空!', 'ERROR',wx.ICON_ERROR)
            self.Message.ShowModal()
            self.Message.Destroy()
    def command3_event(self, event):
        self.Message = wx.MessageDialog(self, '对不起,此功能暂时未开放!', 'ERROR', wx.ICON_ERROR)
        self.Message.ShowModal()
        self.Message.Destroy()
    def command2_event(self, event):
        self.text2.SetValue('')
        self.text4.SetValue('')
        self.text5.SetLabel('\n\n')
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()
效果如下,具体的界面各方面从设置布局开始,分为两个布局。一个是登录界面布局

另一个布局用在存放gird表格

然后是模拟登录获取数据的爬虫

具体的操作就不说了,之前的博文关于模拟登录教务系统有细说了, 此爬虫类主要是爬取学生姓名,学院,学号,以及成绩单 (2.0版本增加一个爬取个人课程表的类)

首先是爬取个人成绩单的类

class get_data_from_zsc():
    def __init__(self, userAccount, password):
        driver_path = r'E:\py\chromedriver\chromedriver.exe'
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')

        driver = webdriver.Chrome(executable_path=driver_path, chrome_options=chrome_options)

        driver.get('http://jwgln.zsc.edu.cn/jsxsd/')
        driver.implicitly_wait(1)
        driver.find_element_by_id("userAccount").send_keys(userAccount)
        driver.find_element_by_id("userPassword").send_keys(password)
        driver.find_element_by_xpath('//*[@id="btnSubmit"]').click()  # 用click模拟浏览器点击
        driver.implicitly_wait(1)
        self.my_information = []
        self.my_score_list = []
        self.result = self.if_or_get_data(driver)
    def if_or_get_data(self,driver):
        if '用户名或密码错误' in driver.page_source:
            driver.close()
            driver.quit()
            return False
        else:
            driver1 = self.get_course1(driver)
            self.get_course2(driver1)
            return True
    def get_course1(self,driver):
        #获取姓名,学号
        bs = BeautifulSoup(driver.page_source, 'lxml')
        information = list(bs.find('div',attrs ={'class':"block1text"}))
        self.my_information.append(information[0].split(":")[1])
        self.my_information.append(information[2].split(":")[1])
        #获取成绩
        driver.find_element_by_xpath('//*[@class="block7"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@id="btn_query"]').click()
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td')[1:]
        my_score_detail = list(my_score_detail)
        score_list = [i.string for i in my_score_detail]
        for i in range(0, len(score_list), 14):
            course_list = []
            for j in range(i+1, i + 14):
                if score_list[j]== None:
                    course_list.append('\n')
                else:
                    course_list.append(score_list[j])
            self.my_score_list.append(course_list)
        return  driver
    #获得学院
    def get_course2(self, driver):
        driver.find_element_by_xpath('//*[@title="培养管理"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/pyfa/pyfa_query"]').click()
        # 用bs4进行数据筛选
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td', attrs={'align': "left"})
        my_score_detail = list(my_score_detail)
        my_score_list = [i.string for i in my_score_detail]
        Map = dict()
        for i in range(len(my_score_list)):
            if i % 4 == 3:
                if my_score_list[i] not in Map.keys():
                    Map[my_score_list[i]] = 0
                else:
                    Map[my_score_list[i]] = Map[my_score_list[i]] + 1
        college = max(Map.keys(), key=(lambda x: Map[x]))
        self.my_information.append(college)
        driver.close()
        driver.quit()

然后是爬取个人课程表的类

class get_data_from_zsc2():
    def __init__(self, userAccount, password):
        driver_path = r'E:\py\chromedriver\chromedriver.exe'
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')

        driver = webdriver.Chrome(executable_path=driver_path, chrome_options=chrome_options)
        self.all_data = []
        driver.get('http://jwgln.zsc.edu.cn/jsxsd/')
        driver.implicitly_wait(1)
        driver.find_element_by_id("userAccount").send_keys(userAccount)
        driver.find_element_by_id("userPassword").send_keys(password)
        driver.find_element_by_xpath('//*[@id="btnSubmit"]').click()  # 用click模拟浏览器点击
        driver.implicitly_wait(1)
        self.my_information = []
        self.my_score_list = []
        self.result = self.if_or_get_data(driver)
    def if_or_get_data(self,driver):
        if '用户名或密码错误' in driver.page_source:
            driver.close()
            driver.quit()
            return False
        else:
            driver1 = self.get_course1(driver)
            self.get_course2(driver1)
            return True
    def get_course1(self,driver):
        #获取姓名,学号
        bs = BeautifulSoup(driver.page_source, 'lxml')
        information = list(bs.find('div',attrs ={'class':"block1text"}))
        self.my_information.append(information[0].split(":")[1])
        self.my_information.append(information[2].split(":")[1])
        #获取个人课程表
        driver.find_element_by_xpath('//*[@class="block4"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/xskb/xskb_list.do"]').click()
        time.sleep(1)
        #页面弹窗点击确认
        try:
            alt = driver.switch_to_alert()
            alt.accept()
        except:
            pass
        try:
            Select(driver.find_element_by_id("xnxq01id")).select_by_value("2019-2020-2").click()
        except:
            pass
        soup = BeautifulSoup(driver.page_source, 'lxml')
        page = soup.find_all('div', attrs={'class': "kbcontent"})
        teachers1, teachers2 = [], []
        weeks1, weeks2 = [], []
        classrooms1, classrooms2 = [], []
        for i in page:
            teachers1.append(i.find('font', attrs={'title': '老师'}))
            weeks1.append(i.find('font', attrs={'title': '周次(节次)'}))
            classrooms1.append(i.find('font', attrs={'title': '教室'}))
        my_detail = list(page)
        for i in teachers1:
            if i == None:
                teachers2.append('\n')
            else:
                teachers2.append(i.string)
        for i in weeks1:
            if i == None:
                weeks2.append('\n')
            else:
                weeks2.append('\n' + i.string)
        for i in classrooms1:
            if i == None:
                classrooms2.append('\n')
            else:
                classrooms2.append('\n' + i.string)
        pitch_number = ['(上午)\n第1,2节\n(08:00-08:45)\n(08:55-09:40)', '(上午)\n第3,4节\n(10:00-10:45)\n(10:55-11:40)',
                        '(下午)\n第5,6节\n(14:30-15:15)\n(15:25-16:10)', '(下午)\n第7,8节\n(16:20-16:05)\n(17:15-18:00)',
                        '(晚上)\n第9,10节\n(19:30-20:15)\n(20:25-21:10)', '第11,12节', '第13,14节']
        temp = []
        temp.append(pitch_number[0])
        num = 0
        pnum = 0
        for i in range(len(my_detail)):
            if my_detail[i].text == '\xa0':
                temp.append('\n\n\n')
            else:
                temp.append(my_detail[i].text.split(teachers2[i])[0] + '\n' + teachers2[i] + weeks2[i] + classrooms2[i])
            num = num + 1
            if num == 7:
                self.all_data.append(temp)
                temp = []
                pnum = pnum + 1
                temp.append(pitch_number[pnum])
                num = 0
        page2 = soup.find('td', attrs={'colspan': "7"})
        BZ = ['备注:' + page2.text, '\n', '\n', '\n', '\n', '\n', '\n', '\n']
        self.all_data.append(BZ)
        return  driver
    #获得学院
    def get_course2(self, driver):
        driver.find_element_by_xpath('//*[@title="培养管理"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/pyfa/pyfa_query"]').click()
        # 用bs4进行数据筛选
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td', attrs={'align': "left"})
        my_score_detail = list(my_score_detail)
        my_score_list = [i.string for i in my_score_detail]
        Map = dict()
        for i in range(len(my_score_list)):
            if i % 4 == 3:
                if my_score_list[i] not in Map.keys():
                    Map[my_score_list[i]] = 0
                else:
                    Map[my_score_list[i]] = Map[my_score_list[i]] + 1
        college = max(Map.keys(), key=(lambda x: Map[x]))
        self.my_information.append(college)
        driver.close()
        driver.quit()

最后是wx.grid的表格类

依旧是继承wx.grid.Grid,来重构类

class mygrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent=parent, id=-1)
        #self.CreateGrid(0, 7)
        self.SetDefaultCellBackgroundColour('#BFD8D8')#parent.BackgroundColour
        self.SetDefaultCellTextColour("#000000")
        self.CreateGrid(0, 13) #设置初始化时的行数和列数
        #为列定义初始化名字
        for i in range(13):
            self.SetColLabelValue(i,'列名')
        self.header = []
     #初始化函数,作用跟上面差不多
    def ff(self):
        self.ClearGrid() #清除表格数据
        if self.GetNumberRows()>0:
            self.DeleteRows(0, self.GetNumberRows()) #删除所有行
        #self.DeleteCols(0, self.GetNumberCols())
        for i in range(13):
            self.SetColLabelValue(i, '列名')
        self.Update()
        self.Refresh()
        self.header = []

当然,要奉上图片资源

这个是背景logo,即是‘中山学院.png’ 下载后更改储存图片的地址即可,图标资源就不提供了,太大了,就是圆标校徽

整体爬取成功的界面样子

1.0版本是下面的样子

2.0版本多了一个爬取个人课程表的功能 成绩单

课程表

最后的最后,奉上所有代码

将chromedriver.exe的存储位置改好,对应的库下载好,图片资源最好下载设置后位置,不弄的话将对应的设置图片代码行注释掉,应该也可以运行,只是会缺少相应的图片

# -*-coding:utf-8-*-
'''
@author Himit_ZH
Date:2020.02.05
'''
from selenium import webdriver # 从selenium导入webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.select import Select
from bs4 import BeautifulSoup
import wx
import wx.grid
import random
import time


sutuo = ['活动名称', '获得学分', '班级审核状态', '院系审核状态', '学校审核状态', '审核截止日期', '申报成功']
grade = ['开课学期', '课程编号', '课程名称', '总成绩', '学分',
                  '平时成绩', '期中成绩', '实验成绩', '期末成绩', '课程属性',
                  '课程性质', '备注', '考试性质']
timetable = ['课程时间','星期一','星期二','星期三','星期四','星期五','星期六','星期日',
             '无','无','无','无','无']
class myFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'ZSC-学生查询系统', pos=(100, 100), size=(1400, 600))
        self.MaxSize = self.Size
        self.MinSize = self.Size
        panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer1 = wx.BoxSizer(wx.VERTICAL)
        sizer3 = wx.BoxSizer(wx.VERTICAL)
        font = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.BOLD)

        #设置窗口以及托盘图标
        icon = wx.Icon()
        icon.CopyFromBitmap(wx.Bitmap(wx.Image(("E:\py\系统图片\zsc.jpg"), wx.BITMAP_TYPE_JPEG)))
        self.SetIcon(icon)

        #设置左边背景学院logo
        image = wx.Image("E:\py\系统图片\中山学院.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        self.background = wx.StaticBitmap(panel, -1, bitmap=image,style=wx.ALIGN_CENTER)
        sizer1.Add(self.background,proportion=10,flag= wx.ALIGN_CENTER_VERTICAL, border=10)

        #设置静态‘用户名'
        self.text1 = wx.StaticText(panel, -1, '用户名:', style=wx.ALIGN_CENTER)
        self.text1.SetFont(font)
        sizer1.Add(self.text1, proportion=2, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #用户名输入框
        self.text2 = wx.TextCtrl(panel, -1, size=(200, -1), style=wx.TE_LEFT)
        self.text2.SetFont(font)
        sizer1.Add(self.text2, proportion=0, flag=wx.ALIGN_CENTER | wx.EXPAND, border=15)

        #设置静态'密码'
        self.text3 = wx.StaticText(panel, -1, '密码:', style=wx.ALIGN_CENTER)
        self.text3.SetFont(font)
        sizer1.Add(self.text3, proportion=2, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #密码输入框
        self.text4 = wx.TextCtrl(panel, -1, size=(200, -1), style=wx.TE_LEFT|wx.TE_PASSWORD|wx.TE_PROCESS_ENTER)
        self.text4.SetFont(font)
        sizer1.Add(self.text4, proportion=0, flag=wx.ALIGN_CENTER | wx.EXPAND, border=15)

        # 设置获取成绩按钮
        self.command1 = wx.Button(panel, -1, '→获取个人成绩单')
        self.command1.SetFont(font)
        self.command1.SetBackgroundColour('#3299CC')
        sizer1.Add(self.command1, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置获取课程表按钮
        self.command4 = wx.Button(panel, -1, '→获取个人课程表')
        self.command4.SetFont(font)
        self.command4.SetBackgroundColour('#DBDB70')
        sizer1.Add(self.command4, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置获取素拓分按钮
        self.command3 = wx.Button(panel, -1, '→获取个人素拓分')
        self.command3.SetFont(font)
        self.command3.SetBackgroundColour('#32CC32')
        sizer1.Add(self.command3, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置重置按钮
        self.command2 = wx.Button(panel, -1, '→重置输入框')
        self.command2.SetFont(font)
        self.command2.SetBackgroundColour((random.randint(1, 255), random.randint(0, 255), random.randint(0, 255)))
        sizer1.Add(self.command2, proportion=5, flag=wx.ALIGN_CENTER | wx.EXPAND, border=10)

        #设置消息提示文本
        self.text5 = wx.StaticText(panel, -1, '\n\n', style=wx.ALIGN_CENTER)
        self.text5.SetFont(font)
        self.text5.SetForegroundColour('Red')
        sizer1.Add(self.text5, proportion=15, flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=10)

        #设置个人信息文本
        self.text6 = wx.StaticText(panel, -1, '姓名:')
        self.text7 = wx.StaticText(panel, -1, '学号:')
        self.text8 = wx.StaticText(panel, -1, '学院:')
        sizer1.Add(self.text6, proportion=3, flag=wx.LEFT, border=0)
        sizer1.Add(self.text7, proportion=3, flag=wx.LEFT, border=0)
        sizer1.Add(self.text8, proportion=3, flag=wx.LEFT, border=0)

        #把分布局全部加入整体顶级布局
        sizer.Add(sizer1, flag=wx.EXPAND | wx.ALL, border=20)
        sizer.Add(sizer3, flag=wx.EXPAND | wx.ALL, border=20)
        self.grid = mygrid(panel)
        sizer.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=25)

        self.grid.SetSize((200, 400))

        panel.SetSizer(sizer)

        #四个按钮对应的事件
        self.command1.Bind(wx.EVT_BUTTON, self.command1_event)
        self.command4.Bind(wx.EVT_BUTTON, self.command4_event)
        self.command3.Bind(wx.EVT_BUTTON, self.command3_event)
        self.command2.Bind(wx.EVT_BUTTON, self.command2_event)
        self.Show()

    def command1_event(self, event):
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()
        self.text5.SetLabel(u'\n温馨提示:\n' + '⚪登录信息验证中...')
        self.text5.Update()
        try:
            name = self.text2.GetValue()
            password = self.text4.GetValue()
            courses = get_data_from_zsc1(name,password)
            if courses.result == False:
                self.text5.SetLabel(u'\n温馨提示:\n' + '×用户名或密码错误!' )
            else:
                student_course = courses.my_score_list
                self.text5.SetLabel(u'\n温馨提示:\n' + '√登录成功并获得成绩!')
                self.text6.SetLabel('姓名:' + courses.my_information[0])
                self.text7.SetLabel('学号:' + courses.my_information[1])
                self.text8.SetLabel('学院:' + courses.my_information[2] )
                try:
                    self.grid.header = grade
                    for i in range(len(self.grid.header)):
                        self.grid.SetColLabelValue(i, self.grid.header[i])
                    self.grid.Update()
                    self.grid.Refresh()
                except:
                    pass
                n1 = len(student_course)
                n2 = len(student_course[0])
                self.grid.InsertRows(0, n1)
                for i in range(0, n1):
                    for j in range(0, n2):
                        self.grid.SetCellValue(i, j, student_course[i][j])
                #self.grid.AutoSize() #自动调整单元格大小
        except:
            self.Message = wx.MessageDialog(self, '账号或密码不能为空!', 'ERROR',wx.ICON_ERROR)
            self.Message.ShowModal()
            self.Message.Destroy()

    def command4_event(self, event):
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()
        self.text5.SetLabel(u'\n温馨提示:\n' + '⚪登录信息验证中...')
        self.text5.Update()
        try:
            name = self.text2.GetValue()
            password = self.text4.GetValue()
            courses = get_data_from_zsc2(name,password)
            if courses.result == False:
                self.text5.SetLabel(u'\n温馨提示:\n' + '×用户名或密码错误!' )
            else:
                student_timetable = courses.all_data
                self.text5.SetLabel(u'\n温馨提示:\n' + '√登录成功并获得课程表!')
                self.text6.SetLabel('姓名:' + courses.my_information[0])
                self.text7.SetLabel('学号:' + courses.my_information[1])
                self.text8.SetLabel('学院:' + courses.my_information[2] )
                try:
                    self.grid.header = timetable
                    for i in range(len(self.grid.header)):
                        self.grid.SetColLabelValue(i, self.grid.header[i])
                    self.grid.Update()
                    self.grid.Refresh()
                except:
                    pass
                n1 = len(student_timetable)
                n2 = len(student_timetable[0])
                self.grid.InsertRows(0, n1)
                for i in range(0, n1):
                    for j in range(0, n2):
                        self.grid.SetCellValue(i, j, student_timetable[i][j])
                self.grid.SetCellSize(6, 0, 1, 5) #合并单元格 合并第6行第1个为1x5的单元格
                #设置行的高度
                for i in range(0, n1):
                    self.grid.SetRowSize(i, 80)
                #设置列的宽度
                for j in range(0, n2):
                    self.grid.SetColSize(j, 120)
                #self.grid.AutoSize()
        except:
            self.Message = wx.MessageDialog(self, '账号或密码不能为空!', 'ERROR',wx.ICON_ERROR)
            self.Message.ShowModal()
            self.Message.Destroy()
    def command3_event(self, event):
        self.Message = wx.MessageDialog(self, '对不起,此功能暂时未开放!', 'ERROR', wx.ICON_ERROR)
        self.Message.ShowModal()
        self.Message.Destroy()
    def command2_event(self, event):
        self.text2.SetValue('')
        self.text4.SetValue('')
        self.text5.SetLabel('\n\n')
        self.text6.SetLabel('姓名:')
        self.text7.SetLabel('学号:')
        self.text8.SetLabel('学院:')
        self.grid.ff()
        self.grid.Update()

class mygrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent=parent, id=-1)
        #self.CreateGrid(0, 7)
        self.SetDefaultCellBackgroundColour('#BFD8D8')#parent.BackgroundColour
        self.SetDefaultCellTextColour("#000000")
        self.CreateGrid(0, 13)
        for i in range(13):
            self.SetColLabelValue(i,'列名')
        self.header = []
    def ff(self):
        self.ClearGrid()
        if self.GetNumberRows()>0:
            self.DeleteRows(0, self.GetNumberRows())
        #self.DeleteCols(0, self.GetNumberCols())
        for i in range(13):
            self.SetColLabelValue(i, '列名')
        self.Update()
        self.Refresh()
        self.header = []


class get_data_from_zsc1():
    def __init__(self, userAccount, password):
        driver_path = r'E:\py\chromedriver\chromedriver.exe'
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')

        driver = webdriver.Chrome(executable_path=driver_path, chrome_options=chrome_options)

        driver.get('http://jwgln.zsc.edu.cn/jsxsd/')
        driver.implicitly_wait(1)
        driver.find_element_by_id("userAccount").send_keys(userAccount)
        driver.find_element_by_id("userPassword").send_keys(password)
        driver.find_element_by_xpath('//*[@id="btnSubmit"]').click()  # 用click模拟浏览器点击
        driver.implicitly_wait(1)
        self.my_information = []
        self.my_score_list = []
        self.result = self.if_or_get_data(driver)
    def if_or_get_data(self,driver):
        if '用户名或密码错误' in driver.page_source:
            driver.close()
            driver.quit()
            return False
        else:
            driver1 = self.get_course1(driver)
            self.get_course2(driver1)
            return True
    def get_course1(self,driver):
        #获取姓名,学号
        bs = BeautifulSoup(driver.page_source, 'lxml')
        information = list(bs.find('div',attrs ={'class':"block1text"}))
        self.my_information.append(information[0].split(":")[1])
        self.my_information.append(information[2].split(":")[1])
        #获取成绩
        driver.find_element_by_xpath('//*[@class="block7"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@id="btn_query"]').click()
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td')[1:]
        my_score_detail = list(my_score_detail)
        score_list = [i.string for i in my_score_detail]
        for i in range(0, len(score_list), 14):
            course_list = []
            for j in range(i+1, i + 14):
                if score_list[j]== None:
                    course_list.append('\n')
                else:
                    course_list.append(score_list[j])
            self.my_score_list.append(course_list)
        return  driver
    #获得学院
    def get_course2(self, driver):
        driver.find_element_by_xpath('//*[@title="培养管理"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/pyfa/pyfa_query"]').click()
        # 用bs4进行数据筛选
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td', attrs={'align': "left"})
        my_score_detail = list(my_score_detail)
        my_score_list = [i.string for i in my_score_detail]
        Map = dict()
        for i in range(len(my_score_list)):
            if i % 4 == 3:
                if my_score_list[i] not in Map.keys():
                    Map[my_score_list[i]] = 0
                else:
                    Map[my_score_list[i]] = Map[my_score_list[i]] + 1
        college = max(Map.keys(), key=(lambda x: Map[x]))
        self.my_information.append(college)
        driver.close()
        driver.quit()

class get_data_from_zsc2():
    def __init__(self, userAccount, password):
        driver_path = r'E:\py\chromedriver\chromedriver.exe'
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument('--disable-gpu')

        driver = webdriver.Chrome(executable_path=driver_path, chrome_options=chrome_options)
        self.all_data = []
        driver.get('http://jwgln.zsc.edu.cn/jsxsd/')
        driver.implicitly_wait(1)
        driver.find_element_by_id("userAccount").send_keys(userAccount)
        driver.find_element_by_id("userPassword").send_keys(password)
        driver.find_element_by_xpath('//*[@id="btnSubmit"]').click()  # 用click模拟浏览器点击
        driver.implicitly_wait(1)
        self.my_information = []
        self.my_score_list = []
        self.result = self.if_or_get_data(driver)
    def if_or_get_data(self,driver):
        if '用户名或密码错误' in driver.page_source:
            driver.close()
            driver.quit()
            return False
        else:
            driver1 = self.get_course1(driver)
            self.get_course2(driver1)
            return True
    def get_course1(self,driver):
        #获取姓名,学号
        bs = BeautifulSoup(driver.page_source, 'lxml')
        information = list(bs.find('div',attrs ={'class':"block1text"}))
        self.my_information.append(information[0].split(":")[1])
        self.my_information.append(information[2].split(":")[1])
        #获取个人课程表
        driver.find_element_by_xpath('//*[@class="block4"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/xskb/xskb_list.do"]').click()
        time.sleep(1)
        #页面弹窗点击确认
        try:
            alt = driver.switch_to_alert()
            alt.accept()
        except:
            pass
        try:
            Select(driver.find_element_by_id("xnxq01id")).select_by_value("2019-2020-2").click()
        except:
            pass
        soup = BeautifulSoup(driver.page_source, 'lxml')
        page = soup.find_all('div', attrs={'class': "kbcontent"})
        teachers1, teachers2 = [], []
        weeks1, weeks2 = [], []
        classrooms1, classrooms2 = [], []
        for i in page:
            teachers1.append(i.find('font', attrs={'title': '老师'}))
            weeks1.append(i.find('font', attrs={'title': '周次(节次)'}))
            classrooms1.append(i.find('font', attrs={'title': '教室'}))
        my_detail = list(page)
        for i in teachers1:
            if i == None:
                teachers2.append('\n')
            else:
                teachers2.append(i.string)
        for i in weeks1:
            if i == None:
                weeks2.append('\n')
            else:
                weeks2.append('\n' + i.string)
        for i in classrooms1:
            if i == None:
                classrooms2.append('\n')
            else:
                classrooms2.append('\n' + i.string)
        pitch_number = ['(上午)\n第1,2节\n(08:00-08:45)\n(08:55-09:40)', '(上午)\n第3,4节\n(10:00-10:45)\n(10:55-11:40)',
                        '(下午)\n第5,6节\n(14:30-15:15)\n(15:25-16:10)', '(下午)\n第7,8节\n(16:20-16:05)\n(17:15-18:00)',
                        '(晚上)\n第9,10节\n(19:30-20:15)\n(20:25-21:10)', '第11,12节', '第13,14节']
        temp = []
        temp.append(pitch_number[0])
        num = 0
        pnum = 0
        for i in range(len(my_detail)):
            if my_detail[i].text == '\xa0':
                temp.append('\n\n\n')
            else:
                temp.append(my_detail[i].text.split(teachers2[i])[0] + '\n' + teachers2[i] + weeks2[i] + classrooms2[i])
            num = num + 1
            if num == 7:
                self.all_data.append(temp)
                temp = []
                pnum = pnum + 1
                temp.append(pitch_number[pnum])
                num = 0
        page2 = soup.find('td', attrs={'colspan': "7"})
        BZ = ['备注:' + page2.text, '\n', '\n', '\n', '\n', '\n', '\n', '\n']
        self.all_data.append(BZ)
        return  driver
    #获得学院
    def get_course2(self, driver):
        driver.find_element_by_xpath('//*[@title="培养管理"]').click()
        driver.implicitly_wait(1)
        driver.find_element_by_xpath('//*[@href="/jsxsd/pyfa/pyfa_query"]').click()
        # 用bs4进行数据筛选
        bs = BeautifulSoup(driver.page_source, 'lxml')
        my_score_detail = bs.find_all(name='td', attrs={'align': "left"})
        my_score_detail = list(my_score_detail)
        my_score_list = [i.string for i in my_score_detail]
        Map = dict()
        for i in range(len(my_score_list)):
            if i % 4 == 3:
                if my_score_list[i] not in Map.keys():
                    Map[my_score_list[i]] = 0
                else:
                    Map[my_score_list[i]] = Map[my_score_list[i]] + 1
        college = max(Map.keys(), key=(lambda x: Map[x]))
        self.my_information.append(college)
        driver.close()
        driver.quit()
if __name__ == '__main__':
    app = wx.App()
    frame = myFrame()
    app.MainLoop()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020年4月7日 1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 首先是界面操作
    • 效果如下,具体的界面各方面从设置布局开始,分为两个布局。一个是登录界面布局
      • 另一个布局用在存放gird表格
      • 然后是模拟登录获取数据的爬虫
        • 首先是爬取个人成绩单的类
          • 然后是爬取个人课程表的类
          • 最后是wx.grid的表格类
          • 当然,要奉上图片资源
          • 整体爬取成功的界面样子
          • 最后的最后,奉上所有代码
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档