python爬取教務管理系統


昨天學習了簡單的爬蟲入門,所以臨時起意寫了一個爬取成績的爬蟲,下面講述寫爬蟲全過程,因為剛學爬蟲,所以找到了一個老的登錄頁面,不需要輸入驗證碼

此處隱去學校信息:http://xxxjwc.its.xxu.edu.cn/jsxsd/

成績頁面:http://xxxjwc.its.xxu.edu.cn/jsxsd/kscj/cjcx_list

總體思路:

1、利用賬號和密碼登錄,記錄下cookie信息

2、利用cookie信息去訪問成績頁面

3、利用xpath獲得想要的信息(這一點還沒仔細學,粗略了解下,用的可能不夠好)

一、獲得登錄時發送的url

1.1使用瀏覽器的開發工具

利用Chrome瀏覽器打開教務管理系統網頁,使用F12,點擊network,勾選Preserve log

1.2登錄賬號密碼,利用開發工具找到登錄時發送的url(其實可以從網頁源代碼中看到表單提交的url)

然后再headers的最下方from data里面可以看到發送的是一個名為encoded的數據,如下所示

這並不是常見的賬號和密碼類型,讀取源代碼發現內容如下

function submitForm1(){  
        try{
            var xh = document.getElementById("userAccount").value;
            var pwd = document.getElementById("userPassword").value; 
            if(xh==""){
                alert("用戶名不能為空!");
                return false;
            }
            if(pwd==""){
                alert("密碼不能為空!");
                return false;
            } 
            var account = encodeInp(xh);
            var passwd = encodeInp(pwd);
            var encoded = account+"%%%"+passwd;
            document.getElementById("encoded").value = encoded;
            var jzmmid = document.getElementById("Form1").jzmmid;  
            return true;
        }catch(e){
            alert(e.Message);
            return false;
        }
    }

發現encoded是通過賬號和密碼加密之后再拼接而成的,這里面的encodedInp()是conwork.js下的一個函數,內容如下:

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('b 9="o+/=";p q(a){b e="";b 8,5,7="";b f,g,c,1="";b i=0;m{8=a.h(i++);5=a.h(i++);7=a.h(i++);f=8>>2;g=((8&3)<<4)|(5>>4);c=((5&s)<<2)|(7>>6);1=7&t;k(j(5)){c=1=l}v k(j(7)){1=l}e=e+9.d(f)+9.d(g)+9.d(c)+9.d(1);8=5=7="";f=g=c=1=""}u(i<a.n);r e}',32,32,'|enc4||||chr2||chr3|chr1|keyStr|input|var|enc3|charAt|output|enc1|enc2|charCodeAt||isNaN|if|64|do|length|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|function|encodeInp|return|15|63|while|else'.split('|'),0,{}))

所以我們的賬號和密碼想要加密就需要自己用python重寫這個函數或者直接利用js里面的函數,我選擇的是直接利用js里面的函數,需要下載PyExecJS模塊,然后導入execjs,賬號和密碼生成encoded如下:

#對賬號密碼進行編碼

def make_user_token(username, password):
    with open('conwork.js') as f:
        ctx = execjs.compile(f.read())
        username_encode = ctx.call('encodeInp', username)
        password_encode = ctx.call('encodeInp', password)
    token = username_encode + '%%%' + password_encode
    return token

准備工作完成,下面開始進行登錄從而構建cookie

二、登錄

因為剛學爬蟲,所以就用最基礎的東西來寫,利用http.cookiejar中CookieJar來獲得cookie信息

#1.登錄
def get_opener():
    #1.1創建一個cookiejar
    cookierjar = CookieJar()
    #1.2使用cookierjar創建一個HTTPCookieProcess對象
    handler = request.HTTPCookieProcessor(cookierjar)
    #1.3使用上一步創建的handler創建一個opener
    opener = request.build_opener(handler)
    return opener

#1.4使用opener發送登錄的請求(賬號和密碼),目的是得到cookie
def login(opener,encoded):
    data={}
    data['encoded'] = encoded
    login_url = 'http://xxxjwc.its.xxu.edu.cn/jsxsd/xk/LoginToXk'
    req = request.Request(login_url,data=parse.urlencode(data).encode('utf-8'),headers =headers)
    opener.open(req)

三、訪問成績頁面

#2.訪問成績頁面
def visit_grade(opener):
    grade_url = 'http://xxxjwc.its.xxu.edu.cn/jsxsd/kscj/cjcx_list'
    req=  request.Request(grade_url,headers=headers)
    resp = opener.open(req)
    return resp.read().decode('utf-8')

四、得到所需成績信息

獲得成績頁面之后,可以利用spilt或者xpath來獲得所需要的內容,這里面我選擇的是利用xpath來獲得成績信息

    web_data = visit_grade(opener)
    html = etree.HTML(web_data)
    grade_data = html.xpath('.//*[@id="dataList"]')#注意這個路徑根據自己所需要的路徑設置即可

之后再將里面的信息逐個輸出即可,具體情況根據自己所需來設定。這里面有個注意點的是,如果你爬取的是table里面的數據,

因為瀏覽器會對html文本進行一定的規范化,如果路徑中存在tbody結果是為空的,去掉xpath中的tbody即可

五、總體效果

全部代碼

from urllib import request,parse
from http.cookiejar import CookieJar
from lxml import etree
import execjs

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Mobile Safari/537.36'
}

#1.登錄
def get_opener():
    #1.1創建一個cookiejar
    cookierjar = CookieJar()
    #1.2使用cookierjar創建一個HTTPCookieProcess對象
    handler = request.HTTPCookieProcessor(cookierjar)
    #1.3使用上一步創建的handler創建一個opener
    opener = request.build_opener(handler)
    return opener

#1.4使用opener發送登錄的請求(賬號和密碼),目的是得到cookie
def login(opener,encoded):
    data={}
    data['encoded'] = encoded
    login_url = 'http://xxxjwc.its.xxu.edu.cn/jsxsd/xk/LoginToXk'
    req = request.Request(login_url,data=parse.urlencode(data).encode('utf-8'),headers =headers)
    opener.open(req)
    
#2.訪問成績頁面
def visit_grade(opener):
    grade_url = 'http://xxxjwc.its.xxu.edu.cn/jsxsd/kscj/cjcx_list'
    req=  request.Request(grade_url,headers=headers)
    resp = opener.open(req)
    return resp.read().decode('utf-8')


#對賬號密碼進行編碼

def make_user_token(username, password):
    with open('conwork.js') as f:
        ctx = execjs.compile(f.read())
        username_encode = ctx.call('encodeInp', username)
        password_encode = ctx.call('encodeInp', password)
    token = username_encode + '%%%' + password_encode
    return token

if __name__ =='__main__':
    username= 'xxxxxxxx'
    password= 'xxxxxxxxxxxxxxxxx'
    encoded = make_user_token(username, password)
    opener = get_opener()
    login(opener,encoded)
    web_data = visit_grade(opener)
    html = etree.HTML(web_data)
    grade_data = html.xpath('.//*[@id="dataList"]')
    for i in grade_data[0]:
        n=0
        s=""
        for j in i:
            if n==3:
                s+=j.text
                s+="\t"
            elif n==4:
                s+=j.text
                s+="\t"
            elif n==5:
                for grade in j:
                    s+=grade.text
                    s+="\t"
            elif n==6:
                s+=j.text
                s+="\t"
            n+=1
        print(s)
                
    

一個最基本的爬蟲就做好了,當然這個還很簡單,隨着后期學習的深入,可能會再寫文章改進一下這個。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM