天天看點

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

剛剛進入假期,學校開放了期末成績查詢,奈何正方教務的各種卡頓。很多學弟學妹問有沒有好辦法能夠解決,閑來無事寫了一段自動擷取的爬蟲程式練練手。

環境
  • Python3.7
  • Jupyter
主要庫
  • requests
  • BeautifulSoup
  • PIL
  • pandas
jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

老氣的登入界面...

一、分析及擷取登入送出資料

首先觀察網頁,由于這個地方比較簡單,我們就使用Chrome的開發者工具中的Network抓包。

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

把css 圖檔之類的過濾掉,發現了包含學号、密碼等内容的表單被送出到default2.aspx

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

分析POST過去的字段

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

總共送出了9個參數(因學校而異,不過關鍵字段都差不多),其中txtUserName是學号、TextBox2是密碼、RadioButtonList1是學生選項(登入身份選項),還有個txtSecretCode是驗證碼。

除了這些正常資料外,我發現還有__VIEWSTATE這種特殊字段,這裡做一個簡要介紹。

__VIEWSTATE:

ViewState是 http:// ASP.NET 中用來儲存WEB控件回傳時狀态值一種機制。在WEB窗體(FORM)的設定為runat="server",這個窗體(FORM)會被附加一個隐藏的屬性_VIEWSTATE。_VIEWSTATE中存放了所有控件在ViewState中的狀态值。

ViewState是類Control中的一個域,其他所有控件通過繼承Control來獲得了ViewState功能。它的類型是system.Web.UI.StateBag,一個名稱/值的對象集合。

當請求某個頁面時, http:// ASP.NET 把所有控件的狀态序列化成一個字元串,然後做為窗體的隐藏屬性送到用戶端。當用戶端把頁面回傳時, http:// ASP.NET 分析回傳的窗體屬性,并賦給控件對應的值。

現在我們知道這個字段肯定是不可缺少的,那麼它們可以從哪擷取到呢?

我們右鍵檢視網頁的源代碼,在源代碼中發現了type為hidden的輸入框,它們的值正是我們所需要的

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

在這個地方,我們可以構造一個login_info字段作為登入資料:

# post的登入資料
    login_info = {
        "__VIEWSTATE": viewState,
        "txtUserName": user, 
        "TextBox2": pwd,
        "txtSecretCode": checkCode,
        "RadioButtonList1": "%D1%A7%C9%FA",#學生選項
        "Button1": "",
        "lbLanguage": ""
    }
           

對于值的擷取這裡采用BeautifulSoup這個庫來解析

re 
           

這樣我們就獲得了能夠送出的資料字段,可以進行登入操作了,驗證碼部分我們在後面單獨介紹。

二、學生個人成績資訊擷取

我們将擷取好的字段作為登入資料送出至http:/default2.a0spx,這裡中間是每個學校有所不同,需要進行修改。

頭部部分建構

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...
#頭部部分建構
header = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
    "Referer": "http://218.56.144.61/",
    "Host": "218.56.144.61",
    "Cache-Control": "max-age=0"
}
           

現在我們可以擷取到學生個人頁面的html資訊

req = requests.session().post(url='http://******/default2.a0spx', data=data, headers=header)
    geren_html = req.text
    #print(geren_html)
           

用簡單的正則寫了一個歡迎語來表示登入成功(正常騷操作)

z_name = re.compile('<span id="xhxm">(.*?)</span></em>',re.S)
        name = re.findall(z_name,geren_html)
        print('登入成功!'+name[0],'歡迎您')
           
jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

之後觀察個人成績這個位置的源碼和抓取的包

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...
jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

這裡雖然有連結但是如果用header的話...

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

就會這樣,是以我們還是老老實實一步步來。

還是先分析包

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

我們可以直接找到成績查詢的url:http:/xscjcx.aspx?xh=xxxxxx&xm=xxx&gnmkdm=N121605

此URL中xh是學号,xm是經過URL編碼的學生姓名。

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

後面我們要做的和前面所講的差不多,首先要通過GET方法擷取頁面源代碼,從中取得__VIEWSTATE的值,然後再次POST過去。

data={
        'btn_zcj':'%C0%FA%C4%EA%B3%C9%BC%A8',#學年成績:btn_xn 曆年成績:btn_zcj
        'ddlXN':'',
        'ddlXQ':'',
        '__EVENTVALIDATION': '',
        '__EVENTTARGET':'',   
        '__EVENTARGUMENT' :'',
        '__VIEWSTATE':'',
        'hidLanguage':'',
        'ddl_kcxz':'',
    }
    
    #生成績頁面擷取關鍵字段
    cj_html_1=S.get('http://*****/xscjcx.aspx?xh='+xh+'&xm='+xm+'&gnmkdm=N121605',headers=header)
    soup=BeautifulSoup(cj_html_1.text,'lxml')
    #print(soup)
    value3=soup.find('input', attrs={'name': '__VIEWSTATE'})['value']
    data['__VIEWSTATE']=value3
    
    cj_html_2 = S.post('http://218.56.144.61/xscjcx.aspx?xh='+xh+'&xm='+xm+'&gnmkdm=N121605',data=data,headers=header)
    #print (cj_html_2.text)
           

我們就擷取到了包含學生的個人成績資訊的網頁源碼

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

之後進行簡單的清洗和處理就OK,這部分是一個見仁見智的問題,我們就不展開說明了。

處理之後進行下步分析或者直接導出都沒問題

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...
jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

在使用爬蟲通路的時候記得一定要留一點餘地

import time
time.sleep(1)
           

畢竟就算着急也盡量不要給别人添麻煩嘛~

三、驗證碼自動處理

驗證碼自動識别這一塊,第三方的pytesseract庫很友善,但是識别率感人。

import pytesseract
from PIL import Image
image = Image.open('vcode.png')
vcode = pytesseract.image_to_string(image)
print (vcode)
           

是以我們使用百度提供的文字識别api

此處特别感謝本專業一位學長的提醒、指導以及提供的部分源碼。

具體實作方式參考

python調用百度通用文字識别接口進行驗證碼識别 - IT技術讨論 - CSDN部落格

在進行識别前要先對圖檔進行預處理,提高識别效率。

二值化

# 二值化算法
def binarizing(img,threshold):
    pixdata = img.load()
    w, h = img.size
    for y in range(h):
        for x in range(w):
            if pixdata[x, y] < threshold:
                pixdata[x, y] = 0
            else:
                pixdata[x, y] = 255
    return img
           

轉化為灰階圖

# 轉化為灰階圖
    image = image.convert('L')
           

去線

# 去除幹擾線算法
def depoint(img):   #input: gray image
    pixdata = img.load()
    w,h = img.size
    for y in range(1,h-1):
        for x in range(1,w-1):
            count = 0
            if pixdata[x,y-1] > 245:
                count = count + 1
            if pixdata[x,y+1] > 245:
                count = count + 1
            if pixdata[x-1,y] > 245:
                count = count + 1
            if pixdata[x+1,y] > 245:
                count = count + 1
            if count > 2:
                pixdata[x,y] = 255
    return img
           

處理完畢後使用接口即可獲得準确率較高一些的識别結果

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

總結

1、由于已經過了查詢成績的高峰期,是以沒能進行登入崩潰的情況測試。具體思路大概是提取崩潰提示頁面中的關鍵詞然後傳回進行繼續通路。

2、由于時間有限,驗證碼識别方面僅僅考慮了便捷性。在後期可以考慮使用有監督的學習方式訓練一個自己的模型。

3、本案例隻是一個小實驗,之後進行小規模的調整即可完成搶課等更多元的功能。

最後,

爬蟲有風險,使用需謹慎~

以上

有幫助的話點個贊再走吧~

完整源碼Github位址:

Vinne6/zfjw_pro​github.com

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

相關引用:

用 Python 實作模拟登入正方教務系統搶課​blog.csdn.net Python模拟登陸正方教務系統并抓取成績單 - lovealways - 部落格園​www.cnblogs.com

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...

利用Python擷取正方教務系統在校成績 - mgsky1的部落格 - CSDN部落格​blog.csdn.net

jfinal擷取url連結上面傳來的string類型的值_Python爬蟲案例——正方教務學生成績擷取(自動識别驗證碼)...