先来说一下我们学校的网站:

http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html

查询成绩需要登录,然后显示各学科成绩,但是只显示成绩而没有绩点,也就是加权平均分。

显然这样手动计算绩点是一件非常麻烦的事情。所以我们可以用python做一个爬虫来解决这个问题。

1.决战前夜

先来准备一下工具:HttpFox插件。

这是一款http协议分析插件,分析页面请求和响应的时间、内容、以及浏览器用到的COOKIE等。

以我为例,安装在火狐上即可,效果如图:

可以非常直观的查看相应的信息。

点击start是开始检测,点击stop暂停检测,点击clear清除内容。

一般在使用之前,点击stop暂停,然后点击clear清屏,确保看到的是访问当前页面获得的数据。

2.深入敌后

下面就去山东大学的成绩查询网站,看一看在登录的时候,到底发送了那些信息。

先来到登录页面,把httpfox打开,clear之后,点击start开启检测:

输入完了个人信息,确保httpfox处于开启状态,然后点击确定提交信息,实现登录。

这个时候可以看到,httpfox检测到了三条信息:

这时点击stop键,确保捕获到的是访问该页面之后反馈的数据,以便我们做爬虫的时候模拟登陆使用。

3.庖丁解牛

乍一看我们拿到了三个数据,两个是GET的一个是POST的,但是它们到底是什么,应该怎么用,我们还一无所知。

所以,我们需要挨个查看一下捕获到的内容。

先看POST的信息:

既然是POST的信息,我们就直接看PostData即可。

可以看到一共POST两个数据,stuid和pwd。

并且从Type的Redirect to可以看出,POST完毕之后跳转到了bks_login2.loginmessage页面。

由此看出,这个数据是点击确定之后提交的表单数据。

点击cookie标签,看看cookie信息:

没错,收到了一个ACCOUNT的cookie,并且在session结束之后自动销毁。

那么提交之后收到了哪些信息呢?

我们来看看后面的两个GET数据。

先看第一个,我们点击content标签可以查看收到的内容,是不是有一种生吞活剥的快感-。-HTML源码暴露无疑了:

看来这个只是显示页面的html源码而已,点击cookie,查看cookie的相关信息:

啊哈,原来html页面的内容是发送了cookie信息之后才接受到的。

再来看看最后一个接收到的信息:

大致看了一下应该只是一个叫做style.css的css文件,对我们没有太大的作用。

4.冷静应战

既然已经知道了我们向服务器发送了什么数据,也知道了我们接收到了什么数据,基本的流程如下:

  • 首先,我们POST学号和密码--->然后返回cookie的值
  • 然后发送cookie给服务器--->返回页面信息。
  • 获取到成绩页面的数据,用正则表达式将成绩和学分单独取出并计算加权平均数。

OK,看上去好像很简单的样纸。那下面我们就来试试看吧。

但是在实验之前,还有一个问题没有解决,就是POST的数据到底发送到了哪里?

再来看一下当初的页面:

很明显是用一个html框架来实现的,也就是说,我们在地址栏看到的地址并不是右边提交表单的地址。

那么怎样才能获得真正的地址-。-右击查看页面源代码:

嗯没错,那个name="w_right"的就是我们要的登录页面。

网站的原来的地址是:

http://jwxt.sdu.edu.cn:7777/zhxt_bks/zhxt_bks.html

所以,真正的表单提交的地址应该是:

http://jwxt.sdu.edu.cn:7777/zhxt_bks/xk_login.html

输入一看,果不其然:

靠居然是清华大学的选课系统。。。目测是我校懒得做页面了就直接借了。。结果连标题都不改一下。。。

但是这个页面依旧不是我们需要的页面,因为我们的POST数据提交到的页面,应该是表单form的ACTION中提交到的页面。

也就是说,我们需要查看源码,来知道POST数据到底发送到了哪里:

嗯,目测这个才是提交POST数据的地址。

整理到地址栏中,完整的地址应该如下:

http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login

(获取的方式很简单,在火狐浏览器中直接点击那个链接就能看到这个链接的地址了)

5.小试牛刀

接下来的任务就是:用python模拟发送一个POST的数据并取到返回的cookie值。

关于cookie的操作可以看看这篇博文:

http://blog.csdn.net/wxg694175346/article/details/8925978

我们先准备一个POST的数据,再准备一个cookie的接收,然后写出源码如下:

[python] view plaincopy
  1. # -*- coding: utf-8 -*-
  2. #---------------------------------------
  3. #   程序:山东大学爬虫
  4. #   版本:0.1
  5. #   作者:why
  6. #   日期:2013-07-12
  7. #   语言:Python 2.7
  8. #   操作:输入学号和密码
  9. #   功能:输出成绩的加权平均值也就是绩点
  10. #---------------------------------------
  11. import urllib
  12. import urllib2
  13. import cookielib
  14. cookie = cookielib.CookieJar()
  15. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
  16. #需要POST的数据#
  17. postdata=urllib.urlencode({
  18. 'stuid':'201100300428',
  19. 'pwd':'921030'
  20. })
  21. #自定义一个请求#
  22. req = urllib2.Request(
  23. url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login',
  24. data = postdata
  25. )
  26. #访问该链接#
  27. result = opener.open(req)
  28. #打印返回的内容#
  29. print result.read()

如此这般之后,再看看运行的效果:

ok,如此这般,我们就算模拟登陆成功了。

6.偷天换日

接下来的任务就是用爬虫获取到学生的成绩。

再来看看源网站。

开启HTTPFOX之后,点击查看成绩,发现捕获到了如下的数据:

点击第一个GET的数据,查看内容可以发现Content就是获取到的成绩的内容。

而获取到的页面链接,从页面源代码中右击查看元素,可以看到点击链接之后跳转的页面(火狐浏览器只需要右击,“查看此框架”,即可):

从而可以得到查看成绩的链接如下:

http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre

7.万事俱备

现在万事俱备啦,所以只需要把链接应用到爬虫里面,看看能否查看到成绩的页面。

从httpfox可以看到,我们发送了一个cookie才能返回成绩的信息,所以我们就用python模拟一个cookie的发送,以此来请求成绩的信息:

[python] view plaincopy
  1. # -*- coding: utf-8 -*-
  2. #---------------------------------------
  3. #   程序:山东大学爬虫
  4. #   版本:0.1
  5. #   作者:why
  6. #   日期:2013-07-12
  7. #   语言:Python 2.7
  8. #   操作:输入学号和密码
  9. #   功能:输出成绩的加权平均值也就是绩点
  10. #---------------------------------------
  11. import urllib
  12. import urllib2
  13. import cookielib
  14. #初始化一个CookieJar来处理Cookie的信息#
  15. cookie = cookielib.CookieJar()
  16. #创建一个新的opener来使用我们的CookieJar#
  17. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
  18. #需要POST的数据#
  19. postdata=urllib.urlencode({
  20. 'stuid':'201100300428',
  21. 'pwd':'921030'
  22. })
  23. #自定义一个请求#
  24. req = urllib2.Request(
  25. url = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login',
  26. data = postdata
  27. )
  28. #访问该链接#
  29. result = opener.open(req)
  30. #打印返回的内容#
  31. print result.read()
  32. #打印cookie的值
  33. for item in cookie:
  34. print 'Cookie:Name = '+item.name
  35. print 'Cookie:Value = '+item.value
  36. #访问该链接#
  37. result = opener.open('http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre')
  38. #打印返回的内容#
  39. print result.read()

按下F5运行即可,看看捕获到的数据吧:

既然这样就没有什么问题了吧,用正则表达式将数据稍稍处理一下,取出学分和相应的分数就可以了。

8.手到擒来

这么一大堆html源码显然是不利于我们处理的,下面要用正则表达式来抠出必须的数据。

关于正则表达式的教程可以看看这个博文:

http://blog.csdn.net/wxg694175346/article/details/8929576

我们来看看成绩的源码:

既然如此,用正则表达式就易如反掌了。

我们将代码稍稍整理一下,然后用正则来取出数据:

[python] view plaincopy
  1. # -*- coding: utf-8 -*-
  2. #---------------------------------------
  3. #   程序:山东大学爬虫
  4. #   版本:0.1
  5. #   作者:why
  6. #   日期:2013-07-12
  7. #   语言:Python 2.7
  8. #   操作:输入学号和密码
  9. #   功能:输出成绩的加权平均值也就是绩点
  10. #---------------------------------------
  11. import urllib
  12. import urllib2
  13. import cookielib
  14. import re
  15. class SDU_Spider:
  16. # 申明相关的属性
  17. def __init__(self):
  18. self.loginUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login'   # 登录的url
  19. self.resultUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre' # 显示成绩的url
  20. self.cookieJar = cookielib.CookieJar()                                      # 初始化一个CookieJar来处理Cookie的信息
  21. self.postdata=urllib.urlencode({'stuid':'201100300428','pwd':'921030'})     # POST的数据
  22. self.weights = []   #存储权重,也就是学分
  23. self.points = []    #存储分数,也就是成绩
  24. self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))
  25. def sdu_init(self):
  26. # 初始化链接并且获取cookie
  27. myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata)   # 自定义一个请求
  28. result = self.opener.open(myRequest)            # 访问登录页面,获取到必须的cookie的值
  29. result = self.opener.open(self.resultUrl)       # 访问成绩页面,获得成绩的数据
  30. # 打印返回的内容
  31. # print result.read()
  32. self.deal_data(result.read().decode('gbk'))
  33. self.print_data(self.weights);
  34. self.print_data(self.points);
  35. # 将内容从页面代码中抠出来
  36. def deal_data(self,myPage):
  37. myItems = re.findall('<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>',myPage,re.S)     #获取到学分
  38. for item in myItems:
  39. self.weights.append(item[0].encode('gbk'))
  40. self.points.append(item[1].encode('gbk'))
  41. # 将内容从页面代码中抠出来
  42. def print_data(self,items):
  43. for item in items:
  44. print item
  45. #调用
  46. mySpider = SDU_Spider()
  47. mySpider.sdu_init()

水平有限,,正则是有点丑,。运行的效果如图:

ok,接下来的只是数据的处理问题了。。

9.凯旋而归

完整的代码如下,至此一个完整的爬虫项目便完工了。

[python] view plaincopy
  1. # -*- coding: utf-8 -*-
  2. #---------------------------------------
  3. #   程序:山东大学爬虫
  4. #   版本:0.1
  5. #   作者:why
  6. #   日期:2013-07-12
  7. #   语言:Python 2.7
  8. #   操作:输入学号和密码
  9. #   功能:输出成绩的加权平均值也就是绩点
  10. #---------------------------------------
  11. import urllib
  12. import urllib2
  13. import cookielib
  14. import re
  15. import string
  16. class SDU_Spider:
  17. # 申明相关的属性
  18. def __init__(self):
  19. self.loginUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bks_login2.login'   # 登录的url
  20. self.resultUrl = 'http://jwxt.sdu.edu.cn:7777/pls/wwwbks/bkscjcx.curscopre' # 显示成绩的url
  21. self.cookieJar = cookielib.CookieJar()                                      # 初始化一个CookieJar来处理Cookie的信息
  22. self.postdata=urllib.urlencode({'stuid':'201100300428','pwd':'921030'})     # POST的数据
  23. self.weights = []   #存储权重,也就是学分
  24. self.points = []    #存储分数,也就是成绩
  25. self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookieJar))
  26. def sdu_init(self):
  27. # 初始化链接并且获取cookie
  28. myRequest = urllib2.Request(url = self.loginUrl,data = self.postdata)   # 自定义一个请求
  29. result = self.opener.open(myRequest)            # 访问登录页面,获取到必须的cookie的值
  30. result = self.opener.open(self.resultUrl)       # 访问成绩页面,获得成绩的数据
  31. # 打印返回的内容
  32. # print result.read()
  33. self.deal_data(result.read().decode('gbk'))
  34. self.calculate_date();
  35. # 将内容从页面代码中抠出来
  36. def deal_data(self,myPage):
  37. myItems = re.findall('<TR>.*?<p.*?<p.*?<p.*?<p.*?<p.*?>(.*?)</p>.*?<p.*?<p.*?>(.*?)</p>.*?</TR>',myPage,re.S)     #获取到学分
  38. for item in myItems:
  39. self.weights.append(item[0].encode('gbk'))
  40. self.points.append(item[1].encode('gbk'))
  41. #计算绩点,如果成绩还没出来,或者成绩是优秀良好,就不运算该成绩
  42. def calculate_date(self):
  43. point = 0.0
  44. weight = 0.0
  45. for i in range(len(self.points)):
  46. if(self.points[i].isdigit()):
  47. point += string.atof(self.points[i])*string.atof(self.weights[i])
  48. weight += string.atof(self.weights[i])
  49. print point/weight
  50. #调用
  51. mySpider = SDU_Spider()
  52. mySpider.sdu_init()

[Python]网络爬虫(十):一个爬虫的诞生全过程(以山东大学绩点运算为例)相关推荐

  1. python网络爬图_Python爬虫爬图片需要什么

    Python爬虫爬图片需要什么?下面用两种方法制作批量爬取网络图片的方法: 第一种方法:基于urllib实现 要点如下: 1.url_request = request.Request(url) 2. ...

  2. 用Python加itchat写一个爬虫脚本每天定时给朋友发微信暖心话

    功能 定时给女朋友发送每日天气.提醒.每日一句. 数据来源 每日一句和上面的大佬一样也是来自ONE·一个 天气信息来自SOJSON 实现效果 代码说明 目录结构 city_dict.py :城市对应编 ...

  3. python网络爬虫学习资料

    第一:Python爬虫学习系列教程(来源于某博主:http://cuiqingcai.com/1052.html) Python版本:2.7 整体目录: 一.爬虫入门 1. Python爬虫入门一之综 ...

  4. python网络爬虫之农大绩点计算器

    最近在家无聊,正好在网上看到一份不错的python教程,于是就学起了python.python是动态语言且具有函数式编程的特点,相比C/C++.java这类静态语言,有很多不同并且很有意思的地方.在学 ...

  5. python网络爬虫权威指南 百度云-Python网络爬虫权威指南 PDF 第2版

    给大家带来的一篇关于Python爬虫相关的电子书资源,介绍了关于Python.网络爬虫方面的内容,本书是由人民邮电出版社出版,格式为PDF,资源大小5.54 MB,瑞安·米切尔编写,目前豆瓣.亚马逊. ...

  6. 微课--Python网络爬虫采集百度搜索结果(例4-5)

    推荐教材: <Python网络程序设计(微课版)>,ISBN:978-7-3025-8312-7,董付国,清华大学出版社,2021年8月出版 配套资源: 教学大纲.445页PPT.91个例 ...

  7. python做爬虫选课_Python2爬虫:以爬取大学本学期绩点为例(实战)

    大家好,本次为大家带来的项目是计算大学本学期绩点.首先说明的是,博主来自山东大学,有属于个人的学生成绩管理系统,需要学号密码才可以登录,不过可能广大读者没有这个学号密码,不能实际进行操作,所以最主要的 ...

  8. python爬虫解析js_python爬虫解析js

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! location.href = localstorage.getitem(url ...

  9. python网络编程实战_Python 异步网络编程实战

    近年来 Python 的发展的非常迅速,"简单"."高效"是 Python 吸引人的一大特色.在国内 Python 开发需求越来越大,Python 具有丰富强大 ...

最新文章

  1. [转载]eclipse的远程调试功能配置
  2. linux 设置开机命令提示符,centos设置开机默认命令行启动
  3. LRU缓存机制—leetcode146
  4. Java常用类(4)--System类
  5. Oracle备份standby,Oracle 11g 利用泠备份恢复standby库
  6. Spring Boot中使用MyBatis注解配置详解
  7. linux-数据库篇-索引
  8. 如何使用Xcode7免费真机调试
  9. java堆外内存6_Java 堆外内存的使用
  10. 基于Spark的电影推荐系统(推荐系统~3)
  11. ffmpeg添加到环境变量_Windows 10系统下安装FFmpeg教程详解
  12. java对接银联商务扫码支付(银联商务扫码支付文档)
  13. 交换机解决电脑IP地址冲突
  14. 各种照片尺寸和分辨率
  15. Unity 抛物线运动脚本(弓箭轨迹)
  16. 刷题笔记 | 朋友圈、岛屿的最大面积、岛屿数量
  17. GB/T28181-2022图像抓拍规范解读及技术实现
  18. 计算机技术变化太快,这世界变化太快!Ps修图进入“智能时代”!
  19. 论文阅读技巧之三遍法
  20. python中text函数的语法_【01】Python基础语法

热门文章

  1. jfinal调用mysql存储过程 封装_jfinal如何调用存储过程?
  2. mysql java 获取周_Java中获取Mysql中datetime类型的数据
  3. Hemberg-lab单细胞转录组数据分析(三)
  4. 如何使用iToolab FixGo for mac修复iPhone/iPad的系统问题
  5. 小学奥数 7834 分成互质组 python
  6. 1.9 编程基础之二分查找 12 最长平台 python
  7. startsBBS在nginx环境下的部署,出现布局错误和验证码不能显示的解决方法
  8. python内置的数据结构_Python内置数据结构
  9. Java笔记-为客户端及服务端创建公私钥的密钥库
  10. JS笔记-前端实现验证码功能