python爬虫正方教务系统

升级版见:http://blog.csdn.net/nghuyong/article/details/52203443

1.前期准备

1.1缘由

某天发现正方教务系统突然升级了,以我们学校江南大学为例: 

原先有一个BUG访问http://202.195.144.163/jndx/default3.aspx可以直接跳过验证码,出现的就是仅仅是用户名和密码一个简洁的框子,现在已经被修复了

所以就必须解决验证码的问题了!

基本思路有几个:

  • 将验证码下载到本地,手工输入验证码
  • 采用验证码的ocr识别算法进行自动破解验证码(经测试识别率太低)
  • 通过网络上的验证码识别接口(收费)

所以最后采用的还是手工输入了。

看了一下超级课程表的解决方案,也是一样的,手工输入验证码 

1.2需要的工具

  • chrome浏览器 F12可以很方便的观察网页交互
  • fiddler 网络抓包工具
  • 使用python开发需要装几个包:1.re 正则表达式 2.requests 强大的网络包 3.lxml xpath的依赖

2.开始爬虫

2.1登陆教务系统

2.1.1基本思路

开启一个session,完成下面的爬虫工作。确保每次的cookie保持一致。先抓取教务系统首页,然后再一次单独抓取验证码,模拟正常在浏览时看不清验证码刷新一次。将获取的验证码并下载到本地,然后填写验证码,一起将登陆数据post过去,实现登陆。

2.1.2登陆分析

  1. 通过审核元素观察到验证码的地址是:http://202.195.144.163/jndx/CheckCode.aspx

  2. 网页登陆查看post数据内容

参数说明:

  • __VIEWSTATE:dDwtMTMxNjk0NzYxNTs7Pv+4BrjArC82wBF5MVEk+YUeOI7j

这是.Net框架特有的一个东西,会变化可以从html的源代码中找到这个值 

  • TextBox1:1030614418

学号参数

  • TextBox2:342626199509064718

密码参数

  • TextBox3:icdc

验证码

  • RadioButtonList1:(unable to decode value)

这个在rawdata里面是%D1%A7%C9%FA 这个是url编码以后的,反url编码转出来的是 学生 

  • Button1:
  • lbLanguage:

这两个参数均为空值

2.1.3代码实现

# author: HuYong
#-*-coding:utf-8-*-
import os
import re
from lxml import etree
import requests
import sys
#设置编码
reload(sys)
sys.setdefaultencoding( "utf-8" )
#初始参数
studentnumber = "1030614418"
password = "342626199509064718"
#访问教务系统
s = requests.session()
url = "http://202.195.144.163/jndx/default2.aspx"
response = s.get(url)
# 使用正则表达式获取 __VIEWSTATE
# __VIEWSTATE = re.findall("name=\"__VIEWSTATE\" value=\"(.*?)\"",response.content)[0]
# 使用xpath获取__VIEWSTATE
selector = etree.HTML(response.content)
__VIEWSTATE = selector.xpath('//*[@id="form1"]/input/@value')[0]
#获取验证码并下载到本地
imgUrl = "http://202.195.144.163/jndx/CheckCode.aspx?"
imgresponse = s.get(imgUrl, stream=True)
print s.cookies
image = imgresponse.content
DstDir = os.getcwd()+"\\"
print("保存验证码到:"+DstDir+"code.jpg"+"\n")
try:
    with open(DstDir+"code.jpg" ,"wb") as jpg:
        jpg.write(image)
except IOError:
    print("IO Error\n")
finally:
    jpg.close
#手动输入验证码
code = raw_input("验证码是:")
#构建post数据
RadioButtonList1 = u"学生".encode('gb2312','replace')
data = {
"RadioButtonList1":RadioButtonList1,
"__VIEWSTATE":__VIEWSTATE,
"TextBox1":studentnumber,
"TextBox2":password,
"TextBox3":code,
"Button1":"",
"lbLanguage":""
}
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36",
}
#登陆教务系统
response = s.post(url,data=data,headers=headers)
print "成功进入教务系统!"

2.2获取教务信息

  • 登陆教务系统后就可以爬取教务系统上的所有信息了。

这是登陆后的首页,可从这里提取姓名和学号信息。通过xpath从html中提取即可。

def getInfor(response,xpath):
    content = response.content.decode('gb2312') #网页源码是gb2312要先解码
    selector = etree.HTML(content)
    infor = selector.xpath(xpath)[0]
    return infor
#获取学生基本信息
text = getInfor(response,'//*[@id="xhxm"]/text()')
text = text.replace(" ","")
studentnumber = text[:10]
studentname = text[10:].replace("同学","")
print "姓名:"+studentname
print "学号:"+studentnumber
  • 下面演示一下爬取课表信息: 
    1. 先抓包分析:

点击课表访问的页面是

http://202.195.144.163/jndx/xskbcx.aspx?xh=1030614418&xm=%BA%FA%D3%C2&gnmkdm=N121603

有几个参数xh为学号,xm为姓名,进行了url编码

注意:headers里面有这样一个参数,一个要有,不然会失败 
Referer:http://202.195.144.163/jndx/xs_main.aspx?xh=1030614418

2.编码实现:

urlStudentname = urllib.quote_plus(str(studentname.encode('gb2312')))
#获取课表
kburl = "http://202.195.144.163/jndx/xskbcx.aspx?xh="+studentnumber+"&xm="+urlStudentname+"&gnmkdm=N121603"

#必须要有Referer这个参数
headers =
 {
"Referer":"http://202.195.144.163/jndx/xs_main.aspx?xh=1030614418",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36",
 }
response = s.get(kburl,headers=headers)
html = response.content.decode("gb2312")
print html

已经爬取了课表的html源码,下面正则表达式即可提取具体课表信息。

3.接下来要做的

  • 能否实现验证码的自动破解

观察验证码,需要先去除噪点,然后再分割,再ocr识别

  • 针对于html的表格,能不能写一个方法,自动解析html的table成json数据类型。
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值