1. 程式人生 > >Python網路爬蟲--模擬登陸教務處網站

Python網路爬蟲--模擬登陸教務處網站

本文主要介紹如何利用Python的requests庫實現學校教務處網站的模擬登陸。關於教務處網站模擬登陸的典型應用主要有課程格子、超級課程表等,教務處網站形式多種多樣,但登陸的基本流程類似,即構建表單-提交表單-實現登陸。本文以我浙的教務處網站為例進行模擬登陸演示。

登陸流程分析

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

這裡寫圖片描述

表單分析

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

這裡寫圖片描述
提交的表單如下:

這裡寫圖片描述

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

獲取表單隱藏值

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

這裡寫圖片描述

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

獲取3次請求的網址

這裡寫圖片描述

同樣的方式獲取第三次請求的網址;

這裡寫圖片描述

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

這裡寫圖片描述

程式碼實現(Python2.7)

匯入相關包

import requests  # 匯入requests
import os
from bs4 import BeautifulSoup  # 匯入bs4中的BeautifulSoup
import time
from PIL import Image

實現第一次請求

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

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

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,以保持登陸狀態。 *

第二次請求

# 第一次重定向
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() # 用於第二次重定向

第三次請求

# 第二次重定向
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介面,進而做出課程表查詢、考試提醒、成績查詢等各種功能型應用。

詳細程式碼及說明可點選我的GitHub

廣告時間

個人部落格:http://ruanshubin.top
GitHub:https://github.com/Ruanshubin/

我的部落格和相關程式碼均會首發在上述兩個平臺,歡迎大家多去逛逛,增加點人氣,O(∩_∩)O哈哈~

這裡寫圖片描述

歡迎您掃一掃上面的二維碼,關注我的微信公眾號!