iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Modern Web

mitmproxy 在網路爬蟲上的各種應用系列 第 6

Day 6 速成爬蟲的第四課 : 送出表單

  • 分享至 

  • xImage
  •  

POST 請求

如果說 GET 請求是單純取得一個頁面,那麼 POST 請求就是送出一些資料,並且交給伺服器端處理。

最常見的情況大概就是登入了。試想一個 POST 請求,表單內容有你的帳號密碼,伺服器確認無誤後,就頒發 Cookies 給你。

iT 邦幫忙的登入表單

如果你想要模擬 iT 邦幫忙的登入,那麼首先,你必須知道該登入表單是怎麼被送出去的 ?

值得高興的是,市面上的瀏覽器通常都有支援開發者工具,你可以用熱鍵 Ctrl + Shift + I 或 F12 按出來,然後檢查網頁的封包。

大家熟知的熱鍵應該是 F12。不過筆者使用的是 60% 鍵盤,沒有上排的 F1 ~ F12,所以習慣按 Ctrl + Shift + I。

https://ithelp.ithome.com.tw/upload/images/20220921/20150913nrjlSwoz9g.png

接著輸入帳號密碼,讓登入這個請求被送出去。

account 和 password 是我的真實帳號密碼,礙於隱私問題,我已經把它塗掉。

筆者使用的瀏覽器是 Firefox。根據瀏覽器的不同,你撈封包的畫面可能會和我不同。

也許你會疑惑,_token 裡面難道不是一個 key value 的資料結構嗎 ? key 是 0 和 1,value 都是 token ?

恩 ... 不是的,那是 Firefox 對陣列的表達方式。確實很容易令人誤會 !

https://ithelp.ithome.com.tw/upload/images/20220921/20150913WFNXFv6qHk.png

_token 是一個陣列,裡面的兩個值看起來都一樣,而且可以在登入頁面的網頁原始碼被搜尋到。

它其實是 CSRF Token。我將會在未來的文章提到,在此範例,我們只要知道,我們必須去滿足表單的內容即可。

https://ithelp.ithome.com.tw/upload/images/20220921/20150913iP9a5S5tCZ.png

實作會像是以下程式碼。

需要特別注意的是,一點進登入頁面的時候,其實就開始了一個 session,並且我們要使用這個頁面給定的 CSRF Token。

所以在第一個請求的時候,我們需要手動抓取 CSRF Token,並且把這份 cookies 保存起來,下次請求繼續使用。

如果你想試試看以下程式碼,account 和 password 記得要手動填入喔 !

import requests
from bs4 import BeautifulSoup


# Get login page
response = requests.get('https://member.ithome.com.tw/login')
soup = BeautifulSoup(response.text, 'html.parser')


# Get csrf token
token = soup.find('input').get('value')


# Get cookies
cookies = response.cookies


# Authentication
response = requests.post(
    'https://member.ithome.com.tw/login',
    data = {
        '_token'   : [token, token],
        'account'  : 'account',
        'password' : 'password'
    },
    cookies = cookies
)

print(response.text)

在執行後用 less 來看 output,可以搜尋到 Yotsuba 這個暱稱,證明我的登入是成功的。

https://ithelp.ithome.com.tw/upload/images/20220921/20150913r5VCCkBLnC.png

Python requests 函式庫的 Session 物件

Python requests 有一個非常強大的功能叫 Session,有如字面上的意思,它可以幫你搞定整個請求過程的 Session。

實際上 Session 在做的事情,主要是幫你紀錄並且保持住你請求後的 Headers。

試想一個情境 : 你想看到的最終頁面,前面還需要經過一個以上的頁面,並且都要保持住 Sesssion,你就必須一直手動保存 Cookies。

比方說購物車吧,你不斷選購商品的時候,還有你到最終付款頁面的時候,為什麼購物車可以持續保持你的狀態 ?

或者就像是剛剛簡單的登入情境就好了,因為輸入帳號密碼,準備登入的時候,還要帶上當前頁面的 CSRF Token,所以你需要處理這個「Session」。

優化 iT 邦幫忙的登入表單實作

讓我們來優化上一段程式碼,可以變成這樣。

利用 Session 物件會幫我們紀錄 Headers 的特性,我們就不用手動處理登入頁面的 Cookies,因為它下一次還會記得我們是誰 !

而且整份程式碼的可讀性也變高了,行為上會非常接近你使用瀏覽器的感覺,畢竟我們用瀏覽器的時候,瀏覽器就自帶紀錄 Cookies 的功能。

import requests
from bs4 import BeautifulSoup


# Create a session
session = requests.Session()


# Get login page
response = session.get('https://member.ithome.com.tw/login')
soup = BeautifulSoup(response.text, 'html.parser')


# Get csrf token
token = soup.find('input').get('value')


# Authentication
response = session.post(
    'https://member.ithome.com.tw/login',
    data = {
        '_token'   : [token, token],
        'account'  : 'account',
        'password' : 'password'
    },
)

print(response.text)

上一篇
Day 5 速成爬蟲的第三課 : 認證
下一篇
Day 7 速成爬蟲的第五課 : 資料儲存
系列文
mitmproxy 在網路爬蟲上的各種應用18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言