使用 requests 登入 learnku

GA17發表於2020-04-16

之前 @TNT_God 讓我寫一篇下載 learnku 的文章,今天跟他聊了發現他已經在寫了,我就不攙和了,不過他用的是直接複製 cookie 的,所以我就寫一篇怎麼用 requests 模組來登入 learnku 的文章。

先開啟瀏覽器,輸入 learnku 的首頁網址 https://learnku.com/ ,然後按 F12 開啟瀏覽器的開發者模式, 這裡我用的是谷歌瀏覽器。
點選登入按鈕,輸入賬號密碼,點選提交,就可以發現開發者模式有新的請求出現。

點選一下,右邊會顯示關於這個請求的資訊。

看到 Form Data 可以知道這是一個 POST 請求,測試多幾遍發現 POST 出去的資料有賬號密碼和兩個固定的引數 remember 和 return_back,token 為變化的引數,根據以往經驗,在 learnku 首頁 html 裡面就能找到這個 token。
(其實那兩個也不是固定引數,但是對登入影響不大就都提交為 yes )

找到所有的東西之後就開始敲程式碼登入啦

from lxml import etree
import requests


# 定義一個會話, 維持cookie
s = requests.Session()

headers = {
    'Host': 'learnku.com',
    'User-Agent': '你的UA'
}
# 更新會話的請求頭
s.headers.update(headers)

# 請求 learnku,拿 token。這裡其實還得到了首頁的 cookie。
response = s.get('https://learnku.com/')
html = etree.HTML(response.text)
# 解析 learnku 首頁拿到 token
token = html.xpath('//meta[@name="csrf-token"]/@content')

# 定義登入要提交的資料
payload = {
    '_token': token,
    'remember': 'yes',
    'return_back': 'yes',
    'username': '賬號',
    'password': '密碼'
}
# 請求登入
s.post('https://learnku.com/auth/login', data=payload)

關於會話和 cookie

(1) 會話

會話,其本來的含義是指有始有終的一系列動作/訊息。比如,打電話時,從拿起電話撥號到結束通話電話這中間的一系列過程可以稱為一個會話。

而在Web中,會話物件用來儲存特定使用者會話所需的屬性及配置資訊。這樣,當使用者在應用程式的Web頁之間跳轉時,儲存在會話物件中的變數將不會丟失,而是在整個使用者會話中一直存在下去。當使用者請求來自應用程式的Web頁時,如果該使用者還沒有會話,則Web伺服器將自動建立一個會話物件。當會話過期或被放棄後,伺服器將終止該會話。

(2) Cookies

Cookies指某些網站為了辨別使用者身份、進行會話跟蹤而儲存在使用者本地終端上的資料。

會話維持

那麼,我們怎樣利用Cookies保持狀態呢?當客戶端第一次請求伺服器時,伺服器會返回一個請求頭中帶有Set-Cookie欄位的響應給客戶端,用來標記是哪一個使用者,客戶端瀏覽器會把 Cookies 儲存起來。當瀏覽器下一次再請求該網站時,瀏覽器會把此 Cookies 放到請求頭一起提交給伺服器,Cookies 攜帶了會話ID資訊,伺服器檢查該 Cookies 即可找到對應的會話是什麼,然後再判斷會話來以此來辨認使用者狀態。

在成功登入某個網站時,伺服器會告訴客戶端設定哪些 Cookies 資訊,在後續訪問頁面時客戶端會把 Cookies 傳送給伺服器,伺服器再找到對應的會話加以判斷。如果會話中的某些設定登入狀態的變數是有效的,那就證明使用者處於登入狀態,此時返回登入之後才可以檢視的網頁內容,瀏覽器再進行解析便可以看到了。

反之,如果傳給伺服器的 Cookies 是無效的,或者會話已經過期了,我們將不能繼續訪問頁面,此時可能會收到錯誤的響應或者跳轉到登入頁面重新登入。

所以,Cookies 和會話需要配合,一個處於客戶端,一個處於服務端,二者共同協作,就實現了登入會話控制。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章