初衷、具体实施 (๑•̀ㅂ•́)و✧
初衷
刚上大一的时候觉得查课表好麻烦啊,查成绩好麻烦啊。就一直想着能不能自己写个小程序用来查询成绩啊查查课表之类的云云。然后上课时听老师说了Python这门语言,第一眼看到这个单词觉得挺有感觉,然后就查了一下,发现了爬虫这个名词……然而一开始连登陆都不会 /(ㄒoㄒ)/~~,绕了很多弯路。今天写下这个小练习的过程以及遇到的困难等等。不足之处还请指出(๑•̀ㅂ•́)و✧准备
基于python3.6, 用到了urllib库(py自带无需安装)以及BeautifulSoup库(命令行下运行:pip3 install bs4)。这里需要讲的是,py2与3的一个区别是,py2中的urllib2在Python3已拆分更名为urllib.request和urllib.error
分析
登录
学校教务处的网址是 http://zhjw.scu.edu.cn/login.jsp。在Chrome下按F12,
输入学号密码登录教务处,会看到在NetWork网络监听中有个LoginAction.do
登陆的过程需要表单。在Headers里可以看到,请求的URL是http://zhjw.scu.edu.cn/loginAction.do,请求方式为Post。往下拉会看到两个参数zjh(学号)和mm(密码)需要提交到这个URL:
啊哈~所以登录只要把这两个参数提交到请求的URL就行了~
遇到的问题及解决
· Chrome的网络监听中如何找到需要查看的文件? 这个问题困扰了我一段时间,期间我也去网上听各种爬虫公开课。我的理解是:登录是需要提交学号和密码的,所以请求方式是Post,文件名应该是Login之类的 · 而在这个文件里有提交的表单的参数,zjh就是学号,mm是密码
成绩的URL
审查一下成绩,会看到: 2015-2016学年秋(两学期) 那么,完整的URL就是http://zhjw.scu.edu.cn/gradeLnAllAction.do?type=ln&oper=qbinfo 当然,这个URL能直接进入,需要cookie,因此需要在代码里加入。
解析成绩
能得到成绩的数据了,接下来就是怎么解析了。由于这个小项目的用户估计只有一个人,对速度没啥要求,就用了BeautifulSoup库。
BeautifulSoup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。 BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,BeautifulSoup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。 BeautifulSoup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
现在,查看http://zhjw.scu.edu.cn/gradeLnAllAction.do?type=ln&oper=qbinfo 及其网页源码,会看到每个科目成绩有课程号,课序号……成绩等7个属性。每个属性都包含在中
代码
# -*- coding:utf-8 -*-from urllib import parse, requestimport http.cookiejarfrom bs4 import BeautifulSoupclass SCU: def __init__(self): # login self.loginURL = 'http://zhjw.scu.edu.cn/loginAction.do' # grades URL self.gradesURL = 'http://zhjw.scu.edu.cn/gradeLnAllAction.do?type=ln&oper=qbinfo' # cookies and postData self.cookies = http.cookiejar.CookieJar() # self.zjh = input() # self.mm = input() self.postData = parse.urlencode({'zjh': '学号', 'mm': '密码'}).encode('utf8') # build opener self.opener = request.build_opener(request.HTTPCookiePRocessor(self.cookies)) # result of grade self.grade = [] def getPage(self): myRequest = request.Request(url=self.loginURL, data=self.postData) self.opener.open(myRequest) # get grades result = self.opener.open(self.gradesURL) html = result.read().decode('gbk') bsObj = BeautifulSoup(html, 'html.parser') resultList = bsObj.findAll('td', {'align': 'center'}) for i, each in enumerate(resultList): self.grade.append(each.get_text().strip()) if (i-6) % 7 == 0: print(self.grade) self.grade = []if __name__ == '__main__': scu = SCU() scu.getPage()'''有了这些数据,接下来可以做一些扩展。<( ̄︶ ̄)↗[GO!] 如果有什么不好的地方还请不吝赐教,有什么问题还请指出~