Python requests 網路請求
在 Python 網頁開發或是 API 串接的過程中,處理 HTTP 請求是核心任務。雖然 Python 內建了 urllib 模組,但其介面設計較為原始且繁瑣。Requests 是一個「專為人類設計」(HTTP for Humans) 的第三方函式庫,它將複雜的 HTTP 通訊封裝成簡潔且語意化的 API,是目前業界處理 API 調用與網頁抓取的標準工具。
安裝 Requests
Requests 是第三方套件,請先確保你的環境中已安裝 pip,然後執行:
pip install requests
基礎語法:GET 與 POST 請求
1. GET 請求 (取得資料)
GET 請求主要用於向伺服器索取資源。你可以直接將變數透過 params 參數傳遞,Requests 會自動處理 URL 編碼。
import requests
# 取得 GitHub API 搜尋專案資料
url = "https://api.github.com/search/repositories"
params = {
"q": "python",
"sort": "stars",
"order": "desc"
}
response = requests.get(url, params=params)
# 快速查看最終產生的 URL
print(f"最終請求 URL: {response.url}")
if response.status_code == 200:
# Requests 內建 JSON 解析器
data = response.json()
items = data.get('items', [])
print(f"熱門 Python 專案數量: {data.get('total_count')}")
for item in items[:3]:
print(f"- {item['name']}: {item['stargazers_count']} stars")
2. POST 請求 (提交資料)
POST 請求常用於提交表單或傳送 JSON 內容給伺服器,例如新增資料或登入。
import requests
url = "https://httpbin.org/post"
payload = {"username": "mike_lee", "role": "admin"}
# 方式 A:提交傳統表單格式 (application/x-www-form-urlencoded)
response_form = requests.post(url, data=payload)
# 方式 B:提交 JSON 格式 (現代 API 與 RESTful 的標準做法)
# 使用 json 參數時,Requests 會自動將 dict 轉為 JSON 並加上正確的 Header
response_json = requests.post(url, json=payload)
print(f"JSON 請求狀態: {response_json.status_code}")
回應物件 (Response Object) 詳解
當你執行請求後,會回傳一個 Response 物件。為了有效處理資料,你必須了解其常用屬性與方法:
| 屬性/方法 | 用途說明 |
|---|---|
status_code | HTTP 狀態碼 (如 200: 成功, 404: 找不到, 500: 伺服器錯誤) |
ok | 布林值,若狀態碼小於 400 則為 True |
text | 回應字串內容 (Requests 會根據 Header 自動推測編碼) |
content | 二進位內容 (通常用於下載圖片、PDF 或壓縮檔) |
json() | 將回應內容解析為 Python 字典 (若回應非 JSON 會拋出 ValueError) |
headers | 回應的標頭資訊 (Dictionary 格式) |
cookies | 伺服器回傳的 Cookie |
request | 原始請求物件,可用於檢查發出的 Header |
進階實務技巧
1. 自定義 Headers 與 User-Agent
許多網站會檢查 User-Agent 來分辨你的身分。如果沒設定,預設的 User-Agent 會顯示為 python-requests/x.x.x,這在某些網站會被直接封鎖。
custom_headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Accept-Language": "zh-TW,zh;q=0.9",
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
response = requests.get("https://example.com/api", headers=custom_headers)
2. Session 物件:保持連線與 Cookie
如果你需要執行一系列相關的請求(例如:先登入,再讀取會員資料),應使用 Session。
# 建立 Session 物件
session = requests.Session()
# 設定 Session 層級的共通 Headers (所有透過此 session 發出的請求都會帶上)
session.headers.update({"x-test": "true"})
# 第一次請求:假設這會取得 Login Cookie
session.post("https://httpbin.org/cookies/set/session_token/xyz123")
# 第二次請求:會自動帶上剛才取得的 Cookie,且連線會被重用 (Pooling) 提升效能
response = session.get("https://httpbin.org/cookies")
print(response.json())
3. 超時設定與例外處理
網路請求可能因為伺服器忙碌或連線問題而卡住。在正式環境中,永遠應該設定 timeout。
from requests.exceptions import HTTPError, Timeout, ConnectionError
try:
# timeout=(連線超時, 讀取超時),單位為秒
response = requests.get("https://api.github.com", timeout=(3.05, 27))
# 若狀態碼非 2xx,主動引發異常
response.raise_for_status()
except Timeout:
print("請求超時,請稍後再試")
except ConnectionError:
print("網路連線失敗,請檢查網路設定")
except HTTPError as http_err:
print(f"HTTP 錯誤發生: {http_err}")
except Exception as err:
print(f"其他不可預知的錯誤: {err}")
4. 檔案下載與串流回應
處理大檔案時,不可使用 response.content 一次讀進記憶體,這會導致 OOM (記憶體溢出)。應使用 stream=True。
url = "https://example.com/large-file.zip"
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open("local_file.zip", "wb") as f:
# 每次寫入 8KB
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
5. 認證機制 (Authentication)
Requests 簡化了常見的認證流程:
# Basic Auth (帳號, 密碼)
from requests.auth import HTTPBasicAuth
requests.get("https://api.example.com", auth=HTTPBasicAuth('user', 'pass'))
# 簡寫格式
requests.get("https://api.example.com", auth=('user', 'pass'))
結語
Requests 的強大在於它隱藏了底層 Socket 通訊與協定握手的複雜性,讓開發者能專注於業務邏輯。
- 快速原型:直接使用
requests.get/post。 - 效能與狀態:使用
requests.Session()。 - 安全性:設定
timeout、正確處理raise_for_status()。
學會 Requests 之後,你可以進一步結合 BeautifulSoup 開發爬蟲,或者串接各大服務的 RESTful API,這是踏入後端開發與資料工程的必修課。