stone

爬一爬北邮教务系统
缘起作为一名狗剧控,最近突然萌发了想要看看豆瓣上电视剧评分的分布情况和比较一下国产电视剧和国外电视剧质量的比较(其...
扫描右侧二维码阅读全文
03
2016/09

爬一爬北邮教务系统

缘起

作为一名狗剧控,最近突然萌发了想要看看豆瓣上电视剧评分的分布情况和比较一下国产电视剧和国外电视剧质量的比较(其实就是想黑国产电视剧),于是就萌发了想要写爬虫的想法,毕竟小的认为自己动手丰衣足食,掌握这一技能还是很方便的。在学习过程中有顺便黑了一下我邮的教务系统,写了这么一个小工具,通过这个小工具可以自动登录,查询课程表和查询成绩并计算平均成绩等。

过程

毕竟现在python3越来越火了,就不要纠结在python2了,直接奔三。现在网上很多的爬虫资料还是用python2来写的,这难免会导致会碰到很多的坑。从python2到python3后,很多包都改变了,其中urllib改动还是较大的,python3中将2中常用的urllib和urllib2合并成了一个包,并且重写组织了包的结构层次。在urllib下分为四个包:error,request,response,parse,Request对象就是放在request包下的,urlencode放在parse下,这个需要注意一下。

但是最终没有采用urllib包,而是使用了requests包,我只能说这个包实在太方便了,在这里强烈推荐。

在访问教务系统时,有一个小的难点,就是会话的保持。一般来说,登录时需要使用到会话功能的。

会话

http是短连接访问,服务器是不会区分请求是否来自之前访问过的用户的,每次收到请求都会当做一个新的用户来处理。我们可以来看看登录的情况:一般来说登录的时候都需要生成一个验证码,当用户打开登录页面时,服务器会随机生成一个验证码和验证码对应的图片,然后将验证码的图片发送给客户端,验证码则会保存在服务器中,当用户填好表单后就将用户名,密码和验证码发送到服务器,服务器在将验证码进行对比,从而检验验证码的正确性。而服务器是怎么知道发来的表单和那个验证码相对应呢?这其中就使用到了cookie和会话技术。

当用户第一次访问一个网站时,服务器可以启动一个会话,在返回的response中加入一个随机生成的cookie,说白了cookie就是一个长的乱序序列,用来唯一标示一个用户,之后客户端每一次发送请求时就会在request带上这个cookie,这样服务器就知道是同一个用户访问服务器。

单独访问生成验证码的地址是没有意义。

爬虫

准确来说今天的这个程序不能算是一个爬虫,程序做的事情也很简单,只是下载一两个网页然后提取其中的一些内容进行了一下整理。但是既然看了爬虫的知识,这里就简单做一下总结。

对于一个爬虫来说,最重要的事情就是要知道自己要去哪里,无论对于小型爬虫,大规模爬虫或则分布式爬虫来说,都是如此。一只爬虫通常需要维护一个任务队列和一个地址集合,要做的事情主要是下面的三步:

1.从任务列表中去到一个地址,访问并下载该网页
2.分析网页,从中提取内容和发现新的地址
3.判断地址是否在集合当中,如果不在则添加到任务队列中

推荐教程:
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
http://cuiqingcai.com/1052.html

程序说明

这个程序主要是访问北邮教务处,提取其中课表和成绩。程序使用了requests包进行网页访问和下载,BS4进行页面解析,pytesseract来识别验证码,prettytable来规范输出字符表格。

程序需在北邮内网中使用,且需要安装谷歌的ocr库tesseract(在mac上安装很方便,win下略麻烦),下面是安装教程地址:
https://github.com/tesseract-ocr/tesseract/wiki

代码

代码比较烂,见笑了

程序源码

# pytesseract使用
img = Image.open("./img.jpg")
imgCode = pytesseract.image_to_string(img)

#requests
session = requests.Session()
url = "http://jwxt.bupt.edu.cn/gradeLnAllAction.do?type=ln&oper=sxinfo&lnsxdm=001"
webPage = session.get(url)

#urllib
cj=cookielib.CookieJar()
opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)

#BS4
from beautifulsoup import BeautifulSoup as BS
soup = BS(r.content, 'html.parser')
table = soup.find_all("td", class_="pageAlign")[1]

#prettytable
from prettytable import PrettyTable as PT
table = PT(['课程名字', '教师', '上课周', '星期', '上课时间', '节数','课室' ,'学分', '类型'])
for item in class_table:
    table.add_row(
        [item['name'], item['teacher'], item['week'], item['weekday'], item['time'], item['long'], item['room'],item['point'],
             item['type']])

print(table)
Last modification:September 7th, 2018 at 08:24 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment