您的位置:首页 > 编程语言 > Python开发

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

2016-10-22 13:10 946 查看
采用模块:

(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、界面展示



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息