最近无聊写了一个Python爬虫,可以根据输入的学号和密码爬取研究生的课程成绩,具体过程记录如下。

工具:

  • Chrome
  • Wireshark
  • Tesseract-ocr+Pytesseract

其中关键步骤在于下载登录界面上的验证码到本地然后输入验证进行登录。

其次要考虑到的是登录提交表单的内容。

奇怪的是利用chrome浏览器的开发者工具竟然不能记录对登录页面提交的表单,真奇怪!!!后来想到以前用到过的强大的wireshark抓包工具,然后用来进行抓取登录页面提交的表单信息。

首先利用chrome浏览器查看登录页面的验证码地址的对应的请求地址。

然后查看登录时请求的地址,发现并不是登录页面的地址,导致后面出现错误。

对于验证码的处理,我是先下载到本地然后再通过画图呈现出来供用户进行输入。

话不多说,下面直接给出Python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# -*- coding:utf-8 -*-
'''
Created on 2017年10月30日

@summary: 利用Python爬虫爬取研究生教务系统信息

@author: dreamhome
'''
import urllib
import urllib2
import cookielib
import re
import json

import matplotlib.pyplot as plt
import matplotlib.image as mpimg # mpimg 用于读取图片

from bs4 import BeautifulSoup

loginUrl = "http://gms.lzu.edu.cn/graduate/j_acegi_security_check"

#cookie
cookie = cookielib.CookieJar()
handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)
#postdata
values = {
'j_username':'',
'j_password':'',
'j_captcha':''
}
#headers
header = {
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36',
'Referer':'http://gms.lzu.edu.cn/graduate/j_acegi_security_check'
}

#输入学号
print "请输入学号:"
values['j_username']=raw_input()
#输入密码
print "请输入密码:"
values['j_password']=raw_input()

#获取验证码

validate_number=opener.open("http://gms.lzu.edu.cn/graduate/getCaptcha.do?")
validate_number_data=validate_number.read()
validate_number_pic=file("validate.jpg",'wb')
validate_number_pic.write(validate_number_data)
validate_number_pic.close()

#显示验证码

validate = mpimg.imread('validate.jpg')
plt.imshow(validate)
plt.axis('off') # 不显示坐标轴
plt.show()

#输入验证码
print '请输入验证码:'
values['j_captcha']=raw_input()

#模拟登陆
postdata = urllib.urlencode(values)
request = urllib2.Request(loginUrl,postdata,header)
response = opener.open(request)
score_url = 'http://gms.lzu.edu.cn/graduate/studentscore/queryScore.do?groupId=&moduleId=25011'
response = opener.open(score_url)
html=response.read()


#判断登录是否成功
if "权限不够,访问被拒绝" in html:
print "登录信息错误,请重新登录"
exit()

#简单数据解析
soup = BeautifulSoup(html.decode('utf8'),'lxml')
trs = soup.findAll('tr')
score_data=[]
for tr in trs:
row=tr.get_text().split()
temp_row=[]
for x in row:
temp_row.append(x.strip())
score_data.append(temp_row)

#输出成绩信息
for x in range(len(score_data)):
for y in score_data[x]:
print y,
print

对于输入信息错误,并没有提供再登录,这个简单就不直接写了,可以再执行一次程序。对于抓取的页面没有做过多的处理,直接提取了关键信息进行输出。

执行结果如下:

--------------------------------------更新------------------------------------------

上面如果可以自动识别验证码将会简化用户查询步骤,因此以下更新自动识别验证码工具使用。

自动识别工具:

  • Tesseract-ocr+Pytesseract

Ubuntu安装过程:

1
2
3
4
5
1.tesseract-ocr安装
sudo apt-get install tesseract-ocr

2.pytesseract安装
sudo pip install pytesseract

Windows用户可参考博客

Python调用自动识别过程如下:

1
2
3
4
5
6
7
from PIL import Image
import pytesseract

# 自动识别验证码
image=Image.open('validate.jpg')
code= pytesseract.image_to_string(image)
print code

利用登录的验证码识别,发现这个工具识别效率确实不怎么样,以后看看还有什么工具可以使用。

联系作者