1. 程式人生 > >自從我學會了Python,教務處的系統我是來去自如!有學弟改分嗎?

自從我學會了Python,教務處的系統我是來去自如!有學弟改分嗎?

嘿嘿 改分是不存在改分的!會被知道的,所以大家還是別想了,今天就是介紹一個爬蟲的小案例,挺適合在室友面前裝逼的!進群“943752371 ”  獲取神祕驚喜!

登陸流程分析 

首先開啟我浙的教務處網站首頁,F12開啟開發者工具,輸入學號、使用者名稱、驗證碼,點選登陸之後,通過開發者工具可以看到,登陸過程包含3次請求,其中2次為暫時重定向(請求返回值為302代表暫時重定向)。

表單分析

點選Headers,如下圖所示,易得第1次請求為表單提交(POST提交)。

提交的表單如下:

其中username, password, authcode

分別為學號、密碼和驗證碼,後面的lt, execution, _eventld為表單隱藏值,表單隱藏值是反爬蟲的初級手段,那麼如何獲取表單隱藏值呢?

獲取表單隱藏值

表單隱藏值可以在實際登陸前,通過登陸介面表單填寫部分的HTML程式碼獲取,由下圖所示:

可以看到,在登陸按鈕的HTML原始碼部分有3項隱藏的Input,觀察name和value值,顯然就是第1次請求POST的表單隱藏值。

獲取3次請求的網址

第1次請求的網址為固定的;

按照上述分析構造表單,模擬POST請求,返回的Response Headers的Location即為第2次請求的網址;

同樣的方式獲取第3次

請求的網址;

訪問第3次請求的網址,即可實現登陸,返回登陸之後的HTML程式碼。

程式碼實現(Python2.7)

匯入相關包

import

requests

# 匯入requests

import

os

from

bs4

import

BeautifulSoup

# 匯入bs4中的BeautifulSoup

import

time

from

PIL

import

Image

實現第1次請求

log_url =

'https://grs.zju.edu.cn/cas/login?locale=zh_CN&service=http%3A%2F%2Fgrs.zju.edu.cn%2Fallogene%2Fpage%2Fhome.htm%3Flocale=zh_CN'

log_headers = {

'Accept'

:

'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'

,

'Accept-Encoding'

:

'gzip, deflate, sdch'

,

'Accept-Language'

:

'zh-CN,zh;q=0.8'

,

'Cache-Control'

:

'max-age=0'

,

'Connection'

:

'keep-alive'

,

'Host'

:

'grs.zju.edu.cn'

,

'Upgrade-Insecure-Requests'

:

'1'

,

'User-Agent'

:

'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'

}

session = requests.

Session

()

log_html = session.

get

(url = log_url, headers = log_headers).text

需要注意的是:在訪問的過程中,因為涉及多次請求,一定要通過Session()的方式來保持網站的對話。

log_html為訪問教務處網站主頁返回的html文件,HTML文件的解析包挺多的,這裡我們選用BeautifulSoup來解析返回文件,獲取表單隱藏值。

log_Soup =

BeautifulSoup

(log_html,

'lxml'

)

submit_list = log_Soup.find(

'li'

, class_=

'mt10 pl10'

).find_all(

'input'

)

item_list = []

for

input_item

in

submit_list:

item_list.append([input_item[

'name'

], input_item[

'value'

]])

log_data = dict(item_list)

獲取驗證碼圖片,進行驗證碼識別,驗證碼識別可以採用OCR方式或者機器學習的方法,這裡我們簡化一下,直接採用手動輸入的方式。

# 獲取驗證碼

auth_jpg_url =

'https://grs.zju.edu.cn/cas/Kaptcha.jpg'

picture = session.

get

(url = auth_jpg_url, headers = log_headers).content

auth_jpg = open(

'Kaptcha.jpg'

,

'wb'

)

auth_jpg.write(picture)

auth_jpg.close()

# 展示驗證碼

log_img =

Image

.open(

'Kaptcha.jpg'

)

log_img.show()

# 輸入驗證碼

authcode = raw_input(

'Please input authcode: '

)

log_data[

'authcode'

] = authcode

構建好表單後,即可實現第1次請求:

data = {

'username'

:

'******'

,

'password'

:

'******'

,

'authcode'

:log_data[

'authcode'

],

'submit'

:

''

,

'lt'

:log_data[

'lt'

],

'execution'

:log_data[

'execution'

],

'_eventId'

:log_data[

'_eventId'

]

}

# 實際登陸

response = session.post(url = log_url, data = data, headers = log_headers, allow_redirects=

False

)

response_headers = dict(response.headers)

cookies = response.cookies.get_dict()

# 用於第一次重定向

需要注意儲存每一次請求的cookies,以保持登陸狀態。

第2次請求

# 第一次重定向

home_first_url = response_headers[

'Location'

]

# session_1 = requests.Session()

response_1 = session.

get

(url = home_first_url, headers = log_headers, cookies = cookies, allow_redirects=

False

)

response_headers_1 = dict(response_1.headers)

cookies_1 = response_1.cookies.get_dict()

# 用於第二次重定向

第3次請求

# 第二次重定向

home_second_url = response_headers_1[

'Location'

]

response_2 = session.

get

(url = home_second_url, headers = log_headers, cookies = cookies_1)

cookies_2 = response_2.cookies.get_dict()

final_html = response_2.text

# 登陸之後返回的html文件

至此,大功告成,成功登陸教務處網站。

下面就可以做一些有意思的事情了,比如利用flask封裝一個API介面,進而做出課程表查詢、考試提醒、成績查詢等各種功能型應用。



作者:919b0c54458f
連結:https://www.jianshu.com/p/c892ba068c4d
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。