HTTP Protocol

網路資料的傳輸是建構在 HTTP 協定之上,所謂的 HTTP 是指 超文本傳輸協定 (HyperText Transfer Protocol, HTTP )是一種用於分佈式、協作式和超媒體訊息系統的應用層協定,超文本(HyperText)其實就是我們講的網頁資料。簡單來說,HTTP 就是一種公認(規定)的網路資料交換的格式。

像這樣基於 Request 與 Response 的交換機制,即是基於 HTTP 的基本規範。

  • Request 是指使用者透過瀏覽器或程式發送的 HTTP 請求 ,一般來說分成 GET 和 POST 兩種方法(差別在於帶資料的方式)。GET 的資料是包含在網址當中,POST 的資料是包含在封包之內的。
  • Response 是網頁伺服器收到 Request 後,回傳給使用者的 HTTP Response,通常會有兩種形式。一種是僅有特定資料格式所組成的字串,稱為是 API;另一種是包含 HTML 的原始碼,稱為 HTML Response。

不管是 Request 或是 Response 的封包都由三種部份所組成:State、Headers、Body

其中的 Headers 代表發送方的資訊,Body 存放要傳輸的資料(也就是我們剛剛講的 API 或是 HTML)。Resquest 的 Headers 代表的是瀏覽器或是發送請求程式,Response 的 Headers 則代表 Server 。所以利用 Headers 來檢查「來源」是否正常合法是一種最基本的驗證機制,例如:Server 收到 Resquest 後,可以馬上利用其 Headers 驗證發送的瀏覽器、時間等等是否為正確作為回傳的依循。

HTTP Headers

所以,當我們利用 Python 程式所發出的 HTTP 請求,很容易被對方的 Server 視為非法的來源。但不用擔心,Python 的 Requset 套件中的請求,有一個參數可以讓我們「偽裝」正常的 Headers,用法如下:

1
2
3
4
5

import requests
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get('...', headers=headers)
response = r.text

這邊我們可以將 headers 封裝成一個 dict 的型態,放在 requests.get 內的 headers 參數。

觀察 HTTP Headers

那下一個問題就會,我們該如何偽裝正常的 Headers 呢?正常的 Headers 應該長怎樣?其實我們可以利用 Chrome 開發者工具觀察瀏覽器發出的請求長怎樣,再將這些內容轉成 Python 中的物件。

最將得到的 Request Headers 的資訊整理成 dict 型態,即可利用 Python 程式偽裝成跟瀏覽器相同的 Headers。這邊有兩個要注意的點:

  1. : 開頭的欄位不用(例如 :authority)
  2. 轉換的過程是包裝成 dict 型態,結果應該類似如下:

補充說明

最後,有兩個常見的問題特別幫大家提出來:

  1. 怎麼判斷是否需要加 Headers?

=> 是否需要加 Headers 其實是決定於對方 Server 會不會利用 Headers 作為檢查。這件事通常無法事先得知,建議直接打打看就知道了!

  1. 在知乎網站加上 Headers 雖然可以正常拉到資料,但會有亂碼的問題?

=> 原因是知乎網站在 accept-encoding 欄位中會得到壓縮後的請求,但他們可能採用進行特殊的機制(非常見的 UTF-8 編碼)導致解碼錯誤,這邊建議可以把這個欄位拿掉即可拉回非壓縮的原始資料。



嗨,我是維元,近期推出一個全新型態的【 Python 資料科學教學實戰營 】,結合多元教學形式及豐富課程經驗幫助你更有效地學習。新課程「 Python 程式設計基礎養成 」正在早鳥募資中,歡迎你一起加入資料領域!誠摯的邀請你跟著我們一起從 Python 入門開始,走進資料科學的世界 🙌



📍 報名頁面: https://dscareer.kolable.app/
📍 報名頁面: https://dscareer.kolable.app/
📍 報名頁面: https://dscareer.kolable.app/


License


本著作由 Chang, Wei-Yaun (v123582) 製作,
創用CC 姓名標示-相同方式分享 3.0 Unported授權條款釋出。