Python_模拟登录(爬取教务系统信息并制作查询界面)

采用模块:
(1)urllib,urllib2,cookielib,BeautifulSoup
(2)wx,py2exe


工作步骤:
(1)解析网站原理,主要获取post数据、密码加密方式相关信息所在真实页面;
(2)爬取所选课程信息与成绩;
(3)利用wxpython制作界面,并生成exe;
(4)发博客增加个人人气。
1、网站解析
(1)headers和post数据可利用浏览器审查元素,刷新页面获取相关元素的get或post方式查询得到,发现post到的数据中除了用户名和密码之外,还有个x和y,多次登录,发现这两个值不是确定的,暂时先不管。除此之外,post的密码是一串密文,暂时也不管,直接复制下来,留作后面备用当作post的数据。
(2)页面框架是多个子页面构成,而且查看源代码看不到相关信息所在的页面,这可头疼了,偶然发现,用ExplorerEdge浏览器直接选中相关的目标,右键——复制地址,OK,成功得到信息真实页面。
已经迫不及待要进入下一步了。
2、爬取信息
(1)建立带cookie的opener,向相关页面发送post数据,包括用户名和密码,上面提到的x和y是否作为发送数据待后面测试,然后获得带cookie的opener;
(2)利用上面的opener打开成绩所在页面和课程信息所在页面,获得页面信息;
(3)对获得的页面代码进行BeautifulSoup处理,或进行正则分析,提取所需要的信息。

3、界面制作及exe生成


4、代码测试
注意事项:
(1)向登录页面可不提交x和y的值,不影响获取页面信息;
(2)密码加密为md5加密,Python中有直接利用的方法,参加模块hashlib;
(3)exe生成时,BeautifulSoup中的lxml解析不能被识别,py2exe操作时,需要加入这样两个参数-p lxml,gzip.
(4)生成exe时对图片的处理有问题,暂时没有解决,只是把图片放到生成的exe文件夹内,而且为ico格式的图片。


5、源代码

(1)爬取信息方法:
sysu_getStudentInfo.py

#-*-coding:utf-8-*-
'''
created by zwg in 2016-10-19
'''
import urllib2
import urllib
from bs4 import BeautifulSoup
import cookielib
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import hashlib
import lxml

class get_data_from_sysu(object):
    def __init__(self,name,password):
        H=hashlib.md5()
        H.update(password)
        password=H.hexdigest()
        password=password.upper()
        post_data = {'j_username': name,
                     'j_password': password}
        post_data = urllib.urlencode(post_data)
        login_url = 'http://ecampus.sysu.edu.cn/zsuyy/login.do'
        info_url = 'http://ecampus.sysu.edu.cn/zsuyy/application/desktop.jsp'
        User_Agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393'
        Referer = 'http://ecampus.sysu.edu.cn/zsuyy/login_normal.jsp'
        Host = 'ecampus.sysu.edu.cn'
        headers = {'User-Agent': User_Agent,
                   'Referer': Referer,
                   'Host': Host,
                   'Connection': 'Keep-Alive',
                   'Content-Type': 'application/x-www-form-urlencoded'}
        cookie = cookielib.CookieJar()
        handle1 = urllib2.HTTPCookieProcessor(cookie)
        myopener = urllib2.build_opener(handle1)
        urllib2.install_opener(myopener)
        myopener.addheaders = headers.items()
        myopener.open(login_url, data=post_data)  # 这时已成功得到可以登录用的cookie
        html_info = myopener.open(info_url, data=post_data).read()
        soup_info = BeautifulSoup(html_info,'lxml')
        info = soup_info.find_all('span', class_="article_subhead1")
        student_name = info[1].string
        student_id = info[0].string
        student_college = info[2].string
        self.password=password
        self.id=student_id
        self.name=student_name
        self.opener=myopener
        self.college=student_college

    def get_course(self):
        course_url = 'http://ecampus.sysu.edu.cn/zsuyy/yanyuan/py/pyjxjh.do?method=enter'
        myopener=self.opener
        html_course = myopener.open(course_url).read()
        soup_course = BeautifulSoup(html_course, 'lxml')
        course = soup_course.find_all('tr', bgcolor='#FFFFFF')
        k = 0
        n=len(course)-1  ## the number of the students' course
        student_course = []
        course_header = []
        one_course=[]
        for i in course:
            S = i.find_all('td')
            if k == 0:
                for j in S:
                    try:
                        course_header.append(str(j.string))
                    except:
                        course_header.append(None)
            else:
                if k==n:
                    continue
                else:
                    for j in S:
                        try:
                            one_course.append(str(j.string))
                        except:
                            one_course.append(None)
                    student_course.append(one_course)
                    one_course=[]
            k+=1
        return course_header,student_course


    def get_grade(self):
        myopener=self.opener
        grade_url = 'http://ecampus.sysu.edu.cn/zsuyy/yanyuan/py/pychengji.do?method=enterChaxun'
        html_grade = myopener.open(grade_url).read()
        soup_grade = BeautifulSoup(html_grade, 'lxml')
        grade = soup_grade.find_all('tr', bgcolor='#FFFFFF')
        k=0
        student_grade={}
        grade_header=[]
        one_grade=[]
        for i in grade[4:len(grade)]:
            S = i.find_all('td')
            if k==0:
                for j in S:
                    try:
                        grade_header.append(str(j.string))
                    except:
                        grade_header.append(None)
            else:
                for j in S:
                    try:
                        one_grade.append(str(j.string))
                    except:
                        one_grade.append(None)
                    student_grade[one_grade[3]]=one_grade[8]
                one_grade=[]
            k+=1
        return grade_header,student_grade



(2)wxpython界面
sysu_login.py

注意:其中有些涉及到图片展示的,使用时需要替换下

#-*-coding:utf-8-*-
'''
created by zwg in 2016=10-20
'''

import wx
import wx.grid
import sysu_getStudentInfo as sysu
class myFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,-1,'SYSU-查成绩',pos=(100,100),size=(1200,600))
        self.MaxSize=self.Size
        self.MinSize=self.Size
        panel=wx.Panel(self,-1)
        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer1=wx.BoxSizer(wx.HORIZONTAL)
        sizer2=wx.BoxSizer(wx.VERTICAL)
        sizer3=wx.BoxSizer(wx.HORIZONTAL)
        font=wx.Font(15,wx.ROMAN,wx.NORMAL,wx.BOLD)
        self.SetIcon(wx.Icon('sysu.ico',wx.BITMAP_TYPE_ICO))
        self.text1=wx.StaticText(panel, -1, '用户名',style=wx.ALIGN_CENTER)
        self.text1.SetFont(font)
        sizer1.Add(self.text1,proportion=0,flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL,border=10)
        self.text2=wx.TextCtrl(panel,-1,size=(150,-1),style=wx.ALIGN_LEFT)
        self.text2.SetFont(font)
        sizer1.Add(self.text2,proportion=1,flag=wx.LEFT|wx.EXPAND,border=5)
        self.text3=wx.StaticText(panel,-1,'密码',style=wx.ALIGN_CENTER)
        self.text3.SetFont(font)
        sizer1.Add(self.text3,proportion=0,flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL,border=15)
        self.text4=wx.TextCtrl(panel,-1,size=(150,-1),style=wx.ALIGN_LEFT|wx.PASSWORD)
        self.text4.SetFont(font)
        sizer1.Add(self.text4,proportion=1,flag=wx.LEFT|wx.EXPAND,border=5)
        self.command1=wx.Button(panel,-1,'确定')
        self.command1.SetFont(font)
        sizer1.Add(self.command1,proportion=0,flag=wx.LEFT|wx.EXPAND,border=15)
        self.command2=wx.Button(panel,-1,'重置')
        self.command2.SetFont(font)
        sizer1.Add(self.command2,proportion=0,flag=wx.LEFT|wx.EXPAND,border=15)

        self.text5=wx.StaticText(panel,-1,'姓名:')
        self.text6=wx.StaticText(panel,-1,'学号:')
        self.text7=wx.StaticText(panel,-1,'学院:')
        sizer2.Add(self.text5,flag=wx.LEFT,border=5)
        sizer2.Add(self.text6,flag=wx.LEFT,border=5)
        sizer2.Add(self.text7,flag=wx.LEFT,border=5)

        # img = wx.Image('head.ico', wx.BITMAP_TYPE_ICO)
        # img.Rescale(70,80)
        # img = img.ConvertToBitmap()
        # self.photo = wx.StaticBitmap(panel, -1, img)
        sizer3.Add(sizer2,flag=wx.ALL,border=10)
        # sizer3.Add(self.photo,flag=wx.LEFT,border=400)

        self.grid=mygrid(panel)
        sizer.Add(sizer1,flag=wx.EXPAND|wx.ALL,border=20)
        sizer.Add(sizer3,flag=wx.EXPAND|wx.ALL,border=20)
        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.command2.Bind(wx.EVT_BUTTON,self.command2_event)
        self.Show()
    def command1_event(self,event):
        try:
            name=self.text2.GetValue()
            password=self.text4.GetValue()
            G=sysu.get_data_from_sysu(name=name,password=password)
            course_header, student_course = G.get_course()
            grade_header, student_grade = G.get_grade()

            self.text5.SetLabel('姓名:'+str(G.name).encode('gbk'))
            self.text6.SetLabel('学号:'+str(G.id).encode('gbk'))
            self.text7.SetLabel('学院:'+str(G.college).encode('gbk'))
            n1=len(student_course)
            n2=len(student_course[0])
            self.grid.InsertRows(0,n1)
            for i in xrange(n1):
                for j in xrange(n2):
                    self.grid.SetCellValue(i,j,str(student_course[i][j]).encode('gbk'))
            for i in xrange(n1):
                try:
                    self.grid.SetCellValue(i,n2,str(student_grade[student_course[i][5]]).encode('gbk'))
                except:
                    self.grid.SetCellValue(i, n2,'暂无成绩')
        except:
            self.Message=wx.MessageDialog(self,'你输入了错误的密码或用户不存在或系统崩溃','ERROR')
            self.Message.ShowModal()
            self.Message.Destroy()
    def command2_event(self,event):
        self.text2.SetValue('')
        self.text4.SetValue('')
        self.text5.SetLabel('姓名:')
        self.text6.SetLabel('学号:')
        self.text7.SetLabel('学院:')
        self.grid.DeleteRows(0,self.grid.GetNumberRows())
class mygrid(wx.grid.Grid):
    def __init__(self,parent):
        wx.grid.Grid.__init__(self,parent=parent,id=-1)
        self.CreateGrid(0,13)
        self.SetDefaultCellBackgroundColour(parent.BackgroundColour)
        header=['开课学年','开课学期','教学班名称',
                '课程代码','课程中文名称','课程性质','课程类别','学时','学分',
                '开课单位','上课时间地点','上课老师','成绩']
        for i in range(len(header)):
            self.SetColLabelValue(i,header[i])
        # n1,n2=self.Size
        # n1=60
        # n2=55
        # self.SetDefaultRowSize(30)
        # self.SetDefaultColSize(100)

if __name__=='__main__':
    app=wx.App()
    frame=myFrame()
    app.MainLoop()


(3)setup
generate_sysu_exe.py

#-*-coding:utf-8-*-
'''
created by zwg in 2016-10-19
'''
from distutils.core import setup
import py2exe
options = {"py2exe":{"compressed": 1, #压缩
                     "optimize": 2,
                     "bundle_files": 1,#所有文件打包成一个exe文件
                     }}


setup(
    options=options,
    name='SYSU_USE',
    windows=['sysu_login.py'],
    zipfile=None)#压缩成一个exe文件
#cmd操作:python generate_sysu_exe.py py2exe -p lxml,gzip

(4)所有文件放在同一个文件夹,cmd进行该文件夹,输入:python generate_sysu_exe.py py2exe -p lxml,gzip


6、界面展示


Python_模拟登录(爬取教务系统信息并制作查询界面)_第1张图片



你可能感兴趣的:(Python,python,爬虫,登录,wxpython)