新版方正教务系统爬虫

来源:互联网 发布:淘宝网恐龙玩具 编辑:程序博客网 时间:2024/04/29 12:32

新版方正教务系统爬虫

技术 解释 Python 2.7 BeautifulSoup 4.X Pycharm 2017 Firefox … Firebug … 新版教务处地址 218.199.228.43

一、基本原理

GET请求

import urllib2# 确定要访问的页面地址url = 'http://****?a=1&b=2'# 构造 request 请求request = urllib2.Request(url)# 返回 response 响应response = urllib2.urlopen(request)# 打印输出结果 html页面result = response.read()print result

POST请求

import urllibimport urllib2data={    username = 'your username'    passwd = 'your password'}# 确定登录页面 -- 根据请求确定url = 'http://******'# 确定请求头 -- request 的请求头信息请参考 http解析headers = {    'User-Agent':...    'Cookie':...    'Referer':...}encoded_data = urllib.urlencode(data)request = urllib2.Request(url=url, data=encoded_data, headers=headers)response = urllib2.urlopen(request)result = response.read()print result

二、模拟登录

获得登录url

教务处首页

根据地址栏的url进行登录,发现并不能成功,总是返回登录界面。使用Firebug进行抓包分析。

抓包分析

发现真正的登陆url为 http://218.197.80.13/xtgl/login_login.html。
并且登录会对cookie进行检查,选择 cookielib.CookieJar() 进行cookie操作,具体代码

def __init__(self):    # 通过登录后获取 cookie    self.cookie = ''    # 获得模拟登陆后的url    self.res_url = ''    # 设置登录成功后的请求头中的Referer    self.referer = ''    # 定义登陆url    self.login_url = 'http://218.197.80.13/xtgl/login_login.html'    # 定义cookie    self.cj = cookielib.CookieJar()    # 定义用户名和密码    self.username = 'your username'    self.passwd = 'your password'    # 对登陆数据进行编码    self.encode_data = urllib.urlencode({        # 从网页中分析得到的表单的属性  yhm 、mm, 具体代码见下        'yhm': self.username,        'mm': self.passwd,    })    self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))# 模拟登录def login(self):    # 构造请求, 在登录时不检查请求头    request = urllib2.Request(self.login_url, self.encode_data)    # 得到反馈结果    response = self.opener.open(request)    # 一系列后续设置    self.res_url = response.geturl()    self.cookie = self.res_url[46:89].upper()    self.referer = self.res_url.replace(';' + self.cookie, '')

由于需要对表单中的用户名和密码框进行分析,故贴上分析代码,也就是获取input框

# 获取界面中的表单提交def parse_form(html):    # 使用 BeautifulSoup进行页面分析,BeautifulSoup的用法见    # https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html    soup = BeautifulSoup(html, 'lxml')    data = {}    for i in soup.find_all('input'):        if i.get('name'):            data[i.get('name')] = i.get('value')    return data

如是需要获取整个页面的代码,使用 download 函数, 下面是download函数的代码

# 第一个参数是需要获得代码的url,第二个是对服务器请求的请求次数,def download(url, num_retries=2):    print('Downloading:', url)    try:        html = urllib2.urlopen(url).read()    except urllib2.URLError as e:        print('Download error: ', e.reason)        html = None        if num_retries > 0:            if hasattr(e, 'code') and 500 <= e.code < 600:                # recursively retry Sxx HTTP errors                return download(url, num_retries - 1)    return html

最后各种参数配置好之后就直接进行登陆操作就可以了,获取到登录之后的url打印出来就好了,因为两个函数都写在类HBUE中,先创建HBUE类,再进行登录就好。

hbue = HBUE()hbue.login()# 打印登陆后的界面download(hbue.res_url)

于是便成功登录到系统,然后接着进行各种操作

三、获得个人信息

新版方正管理系统个人信息不能通过界面直接获取,会抓到空值,通过抓包分析之后,系统通过GET请求获得了首页的个人数据然后显示在主页上,也只有姓名和总学分两项。

个人数据GET请求数据包分析

重要内容 解释 Cookie JSESSIONID=9DF449637264440BE0110************ Referer http://218.197.80.13/xtgl/index_initMenu.html?jsdm=xs&_t=* User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0

其中通过刚开始登录取得的cookie值来填充进headers中,里面的Referer中,后面的_t参数是系统对时间的一个加密参数,但是通过登录成功后的url中可以分析出来

代码:

header = {    'Referer':hbue.res_url,    'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0',    'Cookie':cur_cookie}new_url = 'http://218.197.80.13/xtgl/index_cxYhxxIndex.html?xt=jw&_='+time+'&gnmkdmKey=index&sessionUserKey='+hbue.usernamerequest = urllib2.Request(url=new_url, headers=header)print 'request : ', requestresponse = urllib2.urlopen(request)print response.read()

通过上面这段代码可以获取首页中的个人信息,包括姓名和总学分等。但是更加重要的班级、学院等信息没有获取到,需要进入到个人信息界面进行获取。于是通过Firebug抓包分析,打开个人信息新界面是通过POST请求来获得界面,通过查看数据包中的POST请求,来构造data字典。

headers = {    'Referer': hbue.referer,    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0',    'Cookie': hbue.cookie,}data = {    'dyym': '/xsxxxggl/xsgrxxwh_cxXsgrxx.html',    'gnmkdm': 'N100801',    'gnmkdmKey': 'index',    'gnmkmc': '%E6%9F%A5%E8%AF%A2%E4%B8%AA%E4%BA%BA%E4%BF%A1%E6%81%AF',    'layout': 'func-layout',    'sessionUserKey': hbue.username,}# 对post的数据进行编码encoded_data = urllib.urlencode(data)url = 'http://218.197.80.13/xsxxxggl/xsgrxxwh_cxXsgrxx.html'req = urllib2.Request(url=url, data=encoded_data, headers=headers)response = urllib2.urlopen(req)res = response.read()soup = BeautifulSoup(res, 'lxml')inf_id = {    '学号': 'col_xh',    '姓名': 'col_xm',    '性别': 'col_xbm',    '证件': 'col_zjhm',    '专业': 'col_jg_id',    '学院': 'col_zyh_id',    '班级': 'col_bh_id',}for key, value in inf_id.items():    print key, ' : ', soup.find(id=value).get_text().strip()

通过以上代码构造了POST请求,来访问一个新的界面,并且通过Beautiful来获得需要的各种数据

四、获得所有成绩

同样是在个人信息界面,有一个选项板中是成绩信息。若直接进行获取,则跟在首页上获取个人数据一样是空值,这涉及到对动态网页的访问,想要抓取该数据,需要了解网页是如何加载该数据的。该过程被成为逆向工程。打开该选项卡,在Firebug中查看新的请求,会发现网页通过POST提交来获得了成绩信息。查看返回结果,会发现返回的数据是json格式的,便使用Python的json模块把它解析为一个字典,具体代码如下

# 抓包分析urlurl = 'http://218.197.80.13/cjcx/cjcx_cxDgXscj.html?doType=query&gnmkdmKey=N100801&sessionUserKey=' + hbue.username# 构造请求头headers = {    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0',    'Cookie': hbue.cookie,    'HOST': '218.197.80.13',    'Referer': 'http://218.197.80.13/xsxxxggl/xsgrxxwh_cxXsgrxx.html',}# 通过数据包分析data,其中showCount表示一页显示多少数据# time为1是因为刚进选项卡时提交过一次数据,代号为0,由于初始设置只会显示10条信息,于是再次进行提交,该一个页面显示90条数据,获取全部成绩data = {    '_search': False,    'queryModel.currentPage': '1',    'queryModel.showCount': '90',    'queryModel.sortOrder': 'asc',    'time': '1',    'xh_id': hbue.username,}# 对POST提交数据进行编码encoded_data = urllib.urlencode(data)request = urllib2.Request(url=url, data=encoded_daheaders=headers)response = urllib2.urlopen(request)res = response.read()# 通过json解析来得到字典,然后访问全部的课程名称、教师姓名、课程成绩print '\n所有课程:'for i in json.loads(res)['items']:    print i['kcmc'], i['jsxm'], i['cj']

获取到了所有的课程和结果,其他信息如计算绩点之类的就很简单了

同时课程表、选课信息之类的信息获取也与之类似,通过构造请求来访问就可以了

代码详见:Github

原创粉丝点击