1. 程式人生 > >利用python爬取教務系統中成績

利用python爬取教務系統中成績

最近在學習python,發現通過python爬取網頁資訊確實方便,以前用C++寫了個簡單的爬蟲,爬取指定網頁的資訊,程式碼隨便一寫都幾百行,而要用python完成相同的工作,程式碼量相當少。前幾天看到了一個部落格上講解如何使用python寫的爬蟲爬取成績資訊,看了之後,自己實戰了一番,並且達到了相同的效果。

整個過程和那篇部落格所寫的過程相同,不過由於我們學校的成績查詢系統要輸入驗證碼,所以步驟稍微繁瑣一點。

1.瞭解查詢過程

使用的工具當然也是HttpFox外掛。開啟HttpFox外掛後,我登入了成績系統並且查詢了成績。然後發現httpFox檢測到了很多條資訊:

 

可以看到,當我們第一次訪問成績管理系統的時候,瀏覽器向伺服器傳送了一個GET

請求,而伺服器返回的訊息頭部中給定了Cookie值,如下圖:

 

接下來,瀏覽器向http://gsinfo.whu.edu.cn/servlet/GenImg傳送資訊,獲取驗證碼資訊,可以發現傳送訊息的頭部載入COOKIE資訊:

 

然後,我輸入使用者名稱、密碼、驗證碼登入系統,發現向http://gsinfo.whu.edu.cn/servlet/Login_use這個網址傳送了POST資訊,然後檢查傳送的POST資料,可以看到使用者名稱,密碼,驗證碼,這些資訊都發送過去了。

 

這裡可以看到,who變量表示的是使用者的類別(學生還是老師),id,pwd,yzm分別表示的是學號,密碼和驗證碼,而後面的submit.x

submit.y則不用管它。

登入之後,點選了“查詢成績”的按鈕之後,才最終顯示了成績的頁面,如下圖:

 

運用HttpFox監測之後,我們大致瞭解了查詢成績的基本流程:

首先,我們訪問http://gsinfo.whu.edu.cn,瀏覽器得到Cookie,然後獲取到相應Cookie對應的驗證碼,得到驗證碼圖片的網址是http://gsinfo.whu.edu.cn/servlet/GenImg

其次,我們輸入了學號,密碼,驗證碼後,POSThttp://gsinfo.whu.edu.cn/servlet/Login_use,如果登入成功,則進入到了成績查詢系統。

最後,我們要向http://gsinfo.whu.edu.cn/score/Svlt_QueryScore

這個網址POST查詢資訊,得到最終的查詢頁面。

 2.用python實現模擬登入

知道了成績查詢的大體流程之後,我們就可以使用python來模擬學生登入系統並且查詢成績。整個查詢過程中最重要的一點是要得到登入時的Cookie值,並且後面訪問時也要傳入這個Cookie值,否則會出現登入失敗的情況。我就在驗證碼這裡遇到了點困難,明明輸入的驗證碼就是看到的驗證碼,但是還是登入失敗。最終發現,原來是Cookie的值發生了變化,導致登入時所需要的驗證碼已經不是你得到的驗證碼了。

這裡給出了我寫的python程式碼,使用者需要輸入學號,密碼,和所看到的驗證碼,然後就能看到自己的成績了。

# -*- coding: utf-8 -*-
#模擬登陸武漢大學研究生管理系統
import urllib2,cookielib
import urllib,string
import cStringIO,Image,re
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
opener.addheaders.append(('User-Agent','Mozilla/5.0 (Windows NT 5.1; rv:25.0) Gecko/20100101 Firefox/25.0'))
#opener.addheaders.append(('Connection','Keep-Alive'))
#獲取驗證碼

opener.open(urllib2.Request('http://gsinfo.whu.edu.cn'))

imgurl = 'http://gsinfo.whu.edu.cn/servlet/GenImg'
userid = raw_input("學號:")
pwd = raw_input("密碼:")
res = opener.open(urllib2.Request(imgurl))
tempIm = cStringIO.StringIO(res.read())
im = Image.open(tempIm)
im.show()
yzm = raw_input("驗證碼:")
#需要post的資料
postdata = urllib.urlencode({
    'who':'student',
    'id':userid,
    'pwd':pwd,
    'yzm':yzm,
    'submit.x':'52',
    'submit.y':'13'
    })
req = urllib2.Request(
    url = 'http://gsinfo.whu.edu.cn/servlet/Login_use',
    data = postdata
    )
opener.open(req)
#已經成功進入系統
#查詢成績
postscore = urllib.urlencode({
    'queryType':'1',
    'sYear':'-1',
    'function':'queryScoreStu',
    'Submit':'%C8%B7+%B6%A8',
    'flag':'unnull'})
req = urllib2.Request(
    url = 'http://gsinfo.whu.edu.cn/score/Svlt_QueryScore',
    data = postscore
    )
 
result = opener.open(req)
#返回列印內容
info = result.read()

#列印成績
pattern = r'<TD width="90" height="25" align="center" valign="middle">([^>]*?)</TD>[\s\S]*?height="25">([^>]*?)</TD>[\s\S]*?25[\s\S]*?25[\s\S]*?25[\s\S]*?25[\s\S]*?25[\s\S]*?25">[\s\S]*?25">([^>]*?)</TD>'
p = re.compile(pattern)
score = p.findall(info)
for i in range(len(score)):
    print score[i][1],score[i][0],string.strip(score[i][2])

程式碼的執行結果如下:


總結:本文介紹瞭如何利用python編寫一個小爬蟲,爬取武漢大學研究生管理系統中學生的成績。我目前算是初學python,發現python確實是一門強大的程式語言。畢竟這只是個小練習,還有些不完善,沒有考慮異常的情況。

參考文章: