1. 程式人生 > >python爬蟲例項—獲取北郵教務GPA

python爬蟲例項—獲取北郵教務GPA

# -*- coding: cp936 -*-
#計算北郵教務GPA程式
#by JerryFang
#2013.11.13


import urllib2
import re
import cookielib
from urllib import urlencode
import sys,codecs


def CalcGPA():
    print '''
                    紅領巾(RedCraft)--北郵GPA計算器
         1 計算北郵URP教務系統GPA(僅限內網登入:登入埠為教務系統1)
         2 免修成績不予計算
         3 演算法為:sum(學分*成績)/sum(學分)
         4 使用者名稱輸錯了就費了,這個錯誤還不會寫
                        by JerryFang
    '''
    uname = raw_input('請輸入使用者名稱\n')
    pwd = raw_input('請輸入密碼\n')


    # cookie
    cj = cookielib.LWPCookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    urllib2.install_opener(opener)


    # Login登入POST包中獲得
    user_data = {'type':'sso',
                 'zjh':uname,
                 'mm':pwd
                }
    url_data = urlencode(user_data)




    #使用firefox+HttpFox抓包檢視得到登入url
    req = urllib2.Request(
                          url = 'http://211.68.70.198:8011/jwLoginAction.do',
                          data = url_data
                         )


    result = opener.open(req)




    #抓包獲得成績url
    result = opener.open('http://211.68.70.198:8011/gradeLnAllAction.do?type=ln&oper=fainfo&fajhh=204')


    #WARNING:decode將網頁的編碼轉化為unicode,網頁編碼在html頭部可以看到
    cont = result.read().decode('gb2312')


    #密碼錯誤處理
    if cont.find('''setTimeout('init()',0)''') == 0:
        print '輸入使用者名稱密碼錯誤'
        return 0


    #正則式挖取有用內容
    a = re.compile(u'''<tr.+?>(.+?)</tr>''', re.DOTALL)
    b = re.compile(u'''<td align="center">(.+?)</td>''', re.DOTALL)
    c = re.compile(u'''<p align="center">(.+?)&nbsp;</P>''', re.DOTALL)


    data = []


    myItems = a.findall(cont, re.S)  
    for item in myItems:  
        x = b.findall(item, re.S)
        for i in x:
            #WARNING:如果不用strip正則式無法匹配出c正則式(疑問??)
            j = i.strip()
            ma = c.match(j)
            #將資訊統一為unicode形式
            if ma:
                tmp =  c.findall(j)
                dataItem = tmp[0]
            else:
                dataItem =  j
            #WARNING:將unicode的資料轉化為ascii(str類)儲存
            data.append((dataItem).encode('gbk'))


    l = len(data)
    sumCredit = 0
    sumGPA = 0
    for i in range(l/6):
        #處理免修的特殊情況
        if data[i*6+5] == '免修':
            continue
        credit = float(data[i*6+3])
        grade =  float(data[i*6+5])
        sumGPA += credit*grade
        sumCredit += credit


    print '您的平均成績為'
    print sumGPA/sumCredit
    
CalcGPA()
raw_input('按任意鍵退出')




##爬蟲教程+扒山大教務實戰:http://blog.csdn.net/pleasecallmewhy/article/details/8934726
##py2exe:http://www.cnblogs.com/jans2002/archive/2006/09/30/519393.html