python+requests模擬登錄 學校選課系統

最近學校讓咱們選課,天天都有不一樣的課須要選。。。。而後突發奇想試試用python爬學校選課系統的課程信息html

先把本身的瀏覽器緩存清空,而後在登錄界面按f12 如圖:python

 

 能夠看到登錄時候是須要驗證碼的,驗證碼圖標打算用方法把它存在桌面,手動輸入驗證碼。web

或者能夠買一個自動輸入驗證碼的平臺1快錢能夠幫自動識別100到200次驗證碼,若是這樣作編程

大概過程就是:瀏覽器

1.找到自動輸入驗證碼的平臺緩存

2.閱讀該平臺的API或者手冊服務器

3.用編程語言把驗證碼圖片保存到本身電腦後根據平臺格式要求打包,經過url發送過去cookie

4.用返回的數字輸入到驗證碼窗口app

此次我就簡單作一個須要本身手動輸入驗證碼的模擬登錄腳本算了編程語言

回到正題

因爲我清除了緩存,因此如今至關於第一次登錄,而後我沒有登錄而是直接點了f5刷新,瀏覽器捕捉到的這個請求

能夠看到這個是get請求而且請求頭是兩個Cookie。

Cookie就是我這臺電腦我惟一標識符,當我下次訪問這個網頁時候它會用這個東西來進一步作一下操做,好比:進一步驗證個人身份或者能夠利用Cookie無需帳號密碼直接登錄

這裏有兩個cookie測試看看需用哪一個 下面我再清一次緩存

 

 

 首先上面有兩個cookie下面沒 。下面是我這邊發送給學校的http請求,當我再刷新一次時候

 

能夠看到 下面箭頭 發送給學校的http請求中多了一個cookie並且是最開始的set-cookie中的第二個,接着我再刷新一次

能夠看到發給學校的cookie變成了上次的set-cooki。

那麼能夠看到圖中的 http://xk.qhnu.edu.cn/xsxk/logout.xk 這個網址是用於生成和發送cookie碼的

那麼若是咱們不用瀏覽器登錄改爲用代碼登錄那麼cookie應該是有用的,畢竟是用來標識我這臺電腦的。

雖然不知道這個cookie碼有沒有用 先獲取下來再說吧

這裏須要用到python的request庫

電腦安裝好python後(在官網能夠下載python並安裝)

在配置好環境變量後能夠輸入win+r鍵 後輸入cmd 調出cmd命令窗口

而後輸入 pip install requests 後會自動安裝requests庫

接下來 咱們須要在桌面新建文件並把後綴名改爲 .py

源代碼以下:

1 import requests
2 
3 get_cookie_url='http://xk.qhnu.edu.cn/xsxk/logout.xk'
4 r = requests.get(get_cookie_url)
5 cookie=r.cookies.get_dict()
6 print(cookie)# 輸出cookie

這裏調用了requests的get方法,由於剛纔看圖片上的這個網址用的就是get請求

把結果保存在r裏,而後用

.cookies.get_dict()獲得cookie值

測試結果以下:

能夠看到拿到了cookie碼

:前面的是cookie ID 後面是cookie的值

登錄

接下來使用抓包工具Wireshark 監聽通過這個網頁的流量,也能夠用剛纔的f12看 

輸入帳號密碼和驗證碼後點擊登錄 抓取到如下數據

登錄的時候時候給 http://xk.qhnu.edu.cn/xsxk/loadData.xk(沒有截圖到,能夠本身抓包看到) 這個網址發送了數據而且發送頭包含cookie等信息

而且發送給這個網頁用的方法是get(沒有截圖到,能夠本身抓包看到)

發送的數據變量有

method

username

password

verifcode

那麼後面三個就應該是帳號密碼驗證碼了

經過上面提供的信息,咱們能夠僞造一個發給這個網址的請求

代碼以下

check_header={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',
    'Host': 'xk.qhnu.edu.cn',
}
params={
    'method':'checkLogin',    
    'username':本身的學號,
    'password':本身的帳號,
}
check_url='http://xk.qhnu.edu.cn/xsxk/loadData.xk'

r = requests.get(check_url,params=params,cookies=cookie)
#cookie由以前的代碼得到

可是能夠看到咱們缺乏了一個verifcode變量用來存放所輸入的正確驗證碼值,由於我還要想辦法把驗證碼的圖片保存到桌面,方便看到。

這裏我用谷歌瀏覽器f12的定位功能定位到驗證碼圖片,而且顯示了相對應的html代碼

 

 

從圖中能夠看到 這個驗證碼是由src中的網址生成的,並且d=後面是一串數字,當我再刷新時候這串數字也發生變化

看這串數字不難發現它是一串格林尼治時間,也就是說咱們要得到驗證碼就須要訪問src中的網頁,而且這個網址須要傳遞

一串數字,這串數字是格林尼治時間。我猜是爲了作隨機生成的吧

那麼咱們用get方法來訪問這個網址而且將訪問的數據保存到桌面

代碼:

1 import time
2 
3 jpg_url = 'http://xk.qhnu.edu.cn/xsxk/servlet/ImageServlet?d='+str(int(time.time())*1000)
4 
5 content = requests.get(jpg_url,cookies=cookie).content
6 with open('demo.jpg', 'wb') as fp:
7     fp.write(content)

運行後桌面生成了驗證碼的圖片

在獲取這個驗證碼以前我用抓包工具看了一下 往這個地址發送的數據中又包括了cookie,因此我加上cookie了

在不加cookie的話 就算獲取到了驗證碼圖片 在進行模擬登錄時候根據桌面上的圖登錄老是驗證碼錯誤

在折騰了一段時間後發現驗證碼的生成會和個人cookie相關聯,也就是說,驗證碼的生成不只用到格林尼治時間還用到個人cooki

並將驗證碼與個人cookie綁定,一一對應

而後經過

while(True):
    code = input('請輸入驗證碼:')
    datacode= str(code)

    params['verifyCode']=datacode
    r = requests.get(check_url,params=params,cookies=cookie)
    if re.search('true',r.text):
        print ('驗證碼正確......')
        break
    else:
        print ('驗證碼錯誤,請從新輸入......')
        
    
date['verifyCode']=datacode

將驗證碼加入到前面的date中,發送給/xsxk/loadData.xk,在發送成功後查看返回信息發現驗會有true字符串或者false,那麼我就能夠利用這個來驗證我是否是正確

這樣用到的re庫 須要導入

 

回到剛纔的登錄

繼續看抓包的數據,發現了post方法,通常來講post方法是真正的登錄窗口

post方法前面的 get /xsxk/loadDate......  就是咱們前面實現的get,現應該實現post真正的登錄了

在查看post發送的數據中包含了頭信息,其中包括cookie 和帳號密碼因此咱們用requests的post方法繼續僞造請求

在post結束後學校服務器會返回一個302 found的http狀態碼 這表示瀏覽器將個人數據發送後,會從新跳轉到另一個網頁

不過requests是能夠自動跳轉的,不須要擔憂

代碼 

log_header={    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Origin':'http://xk.qhnu.edu.cn',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',        
    'Referer':'http://xk.qhnu.edu.cn/xsxk/logout.xk',
    'Accept-Encoding':'gzip, deflate',
    'Accept-Language':'zh-CN,zh;q=0.9',
    'Host': 'xk.qhnu.edu.cn',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1'
}
date={
'username':本身的學號,
'password':本身的密碼,
}
log_url='http://xk.qhnu.edu.cn/xsxk/login.xk'

r=requests.post(log_url,data=date,headers=log_header,cookies=cookie)
#傳遞的參數cooki由以前的代碼得到

其中的 date和log_header都是經過抓包看到的 這個網頁須要哪些數據。

代碼寫好後 運行而且抓包發現 與用網頁登錄抓取的包大體相同,經過屢次修改能夠總結以下

經過用網頁登錄抓包發現登錄學校的網址有一下步驟

1.在清空緩存,刷新時(即第一次登錄時),會先向xsxk/logout.xk發送cookie

2.在get驗證碼的所須要的數據中 經過抓包發現須要用到第一步的cookie

3.在登錄前須要向xsxk/loadData.xk發送本身的帳號密碼和驗證碼和cookie

4.登錄時用的是post方法,而且還須要將本身的帳號密碼和以前的驗證碼和cookie發送一次  若是沒有完成第三步那麼不管怎麼登錄都失敗

完整代碼以下

import time
import requests
import re
from bs4 import BeautifulSoup #獲取解析網頁的庫

username=input("帳號")
password=input("密碼")

get_cookie_url='http://xk.qhnu.edu.cn/xsxk/logout.xk'
jpg_url = 'http://xk.qhnu.edu.cn/xsxk/servlet/ImageServlet?d='+str(int(time.time())*1000)
check_url='http://xk.qhnu.edu.cn/xsxk/loadData.xk'
log_url='http://xk.qhnu.edu.cn/xsxk/login.xk'


get_cookie_header={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'
}
check_header={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',
    'Host': 'xk.qhnu.edu.cn',
}
params={
    'method':'checkLogin',    
    'username':username,
    'password':password,
}
log_header={
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Origin':'http://xk.qhnu.edu.cn',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',        
    'Referer':'http://xk.qhnu.edu.cn/xsxk/logout.xk',
    'Accept-Encoding':'gzip, deflate',
    'Accept-Language':'zh-CN,zh;q=0.9',
    'Host': 'xk.qhnu.edu.cn',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1'
}
date={
'username':username,
'password':password,
}


r = requests.get(get_cookie_url)
cookie=r.cookies.get_dict()
#print(cookie) 輸出cookie

content = requests.get(jpg_url,cookies=cookie).content
with open('demo.jpg', 'wb') as fp:
    fp.write(content)

while(True):
    code = input('請輸入驗證碼:')
    datacode= str(code)

    params['verifyCode']=datacode
    r = requests.get(check_url,params=params,cookies=cookie)
    if re.search('true',r.text):
        print ('驗證碼正確......')
        break
    else:
        print ('驗證碼錯誤,請從新輸入......')
        
    
date['verifyCode']=datacode

r=requests.post(log_url,data=date,headers=log_header,cookies=cookie)
#print(r.text)得到網址的源代碼


html=BeautifulSoup(r.text,'lxml')
tagList=html.find('b')

print('#############################################################')
print('進入選課系統成功:')
print(tagList.get_text())
print('#############################################################')

在這裏用了另一個庫 用於解析所獲取的登錄後網頁源代碼

總的來講就是 先用瀏覽器和抓包工具,瀏覽器屢次登錄,用抓包工具和瀏覽器的f12查看登錄前經歷了哪些步驟,哪些網頁,每一個網頁分別發送了哪些數據,用的是get方法仍是post方法

在知道後,用代碼將所須要的數據寫出來並保存後用requests庫的get方法post方法模擬發送數據給學校服務器。最後得到登錄後的網頁源代碼

 

不過。。。我在得到源代碼後發現html中的iframe標籤顯示的是選課的內容,可是我用於分析網頁代碼的庫是BeautifulSoup

它不支持分析iframe內容。。。白忙活了那麼久。

經過在網上查找信息發現selenium這個庫支持分析iframe標籤的內容

因此接下來就去學習用這個庫去獲取學習的選課信息而且自動選課

下次就放用selenium作爬蟲的過程

相關文章
相關標籤/搜索