http.client 教程-如何使用 Python 標準庫發送 HTTP 請求
以下是 http.client?模塊的詳細使用教程,幫助你理解如何使用 Python 標準庫發送 HTTP 請求:
1. http.client 概述
http.client?是 Python 內置的 HTTP 客戶端庫,提供了底層的 HTTP 協議實現,支持:
- 發送 HTTP/1.1 請求
- 處理響應狀態碼、頭信息和內容
- 支持 HTTPS(通過 HTTPSConnection)
- 支持基本認證、Cookie 等功能
優點:無需額外安裝依賴,適合輕量級 HTTP 交互。
缺點:API 較為底層,使用復雜度高于 requests?庫。
2. 基本使用流程
步驟 1:導入模塊并創建連接
import http.client # HTTP 連接 conn = http.client.HTTPConnection("example.com") # HTTPS 連接(默認端口 443) conn = http.client.HTTPSConnection("api.example.com") # 指定端口(如 8080) conn = http.client.HTTPConnection("localhost", 8080) |
步驟 2:發送請求
# 發送 GET 請求 conn.request("GET", "/path/to/resource") # 發送帶參數的 GET 請求 conn.request("GET", "/search?q=python&page=1") # 發送 POST 請求(帶 JSON 數據) headers = {"Content-Type": "application/json"} body = '{"name": "test", "age": 30}' conn.request("POST", "/users", body, headers) |
步驟 3:獲取響應
response = conn.getresponse() # 獲取響應狀態碼 status_code = response.status ?# 如 200, 404, 500 # 獲取響應頭 headers = response.getheaders() # 獲取響應內容 data = response.read() ?# 返回 bytes 類型 text = data.decode("utf-8") ?# 轉為字符串 |
步驟 4:關閉連接
conn.close() |
3. 處理不同類型的請求
GET 請求示例
import http.client conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com") conn.request("GET", "/posts/1") response = conn.getresponse() print(f"狀態碼: {response.status}") print(f"響應頭: {response.getheaders()}") print(f"響應內容: {response.read().decode()}") conn.close() |
POST 請求示例(JSON 數據)
import http.client import json conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com") headers = {"Content-Type": "application/json"} body = json.dumps({"title": "foo", "body": "bar", "userId": 1}) conn.request("POST", "/posts", body, headers) response = conn.getresponse() print(response.read().decode()) conn.close() |
帶參數的 POST 請求(表單數據)
import http.client from urllib.parse import urlencode conn = http.client.HTTPConnection("example.com") headers = {"Content-Type": "application/x-www-form-urlencoded"} params = urlencode({"username": "test", "password": "123456"}) conn.request("POST", "/login", params, headers) response = conn.getresponse() print(response.read().decode()) conn.close() |
4. 處理響應
響應狀態碼
if response.status == 200: ????print("請求成功") elif response.status == 404: ????print("資源不存在") else: ????print(f"錯誤: {response.status}") |
響應頭處理
# 獲取特定頭信息 content_type = response.getheader("Content-Type") print(f"內容類型: {content_type}") # 獲取所有頭信息 headers = response.getheaders() for header, value in headers: ????print(f"{header}: {value}") |
響應內容處理
# 讀取二進制內容 data = response.read() # 根據 Content-Type 解碼 content_type = response.getheader("Content-Type") if "json" in content_type: ????import json ????json_data = json.loads(data) elif "text" in content_type: ????text = data.decode("utf-8") else: ????# 二進制數據(如圖像、文件) ????with open("file.bin", "wb") as f: ????????f.write(data) |
5. 高級用法
設置超時時間
conn = http.client.HTTPSConnection("example.com", timeout=5) ?# 5秒超時 |
處理重定向(301/302)
max_redirects = 3 current_url = "/initial-path" redirect_count = 0 while redirect_count < max_redirects: ????conn.request("GET", current_url) ????response = conn.getresponse() ???? ????if response.status in (301, 302): ????????location = response.getheader("Location") ????????current_url = location ????????redirect_count += 1 ????else: ????????break ?# 非重定向狀態碼,退出循環 |
設置請求頭(如 User-Agent)
headers = { ????"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", ????"Accept": "application/json" } conn.request("GET", "/api/data", headers=headers) |
基本認證
import base64 username = "admin" password = "secret" auth_string = f"{username}:{password}" auth_bytes = base64.b64encode(auth_string.encode()) auth_header = f"Basic {auth_bytes.decode()}" headers = {"Authorization": auth_header} conn.request("GET", "/protected", headers=headers) |
6. 異常處理
import http.client try: ????conn = http.client.HTTPSConnection("nonexistent-domain.com") ????conn.request("GET", "/") ????response = conn.getresponse() except ConnectionRefusedError: ????print("連接被拒絕") except TimeoutError: ????print("連接超時") except http.client.InvalidURL: ????print("無效的 URL") except Exception as e: ????print(f"發生錯誤: {e}") finally: ????if conn: ????????conn.close() |
7. 完整示例:獲取天氣 API 數據
import http.client import json try: ????# 連接到天氣API ????conn = http.client.HTTPSConnection("api.openweathermap.org") ????# API參數(城市ID和API密鑰) ????city_id = "1850147" ?# 東京的城市ID ????api_key = "YOUR_API_KEY" ?# 替換為你的API密鑰 ????# 發送請求 ????conn.request("GET", f"/data/2.5/weather?id={city_id}&appid={api_key}") ????# 獲取響應 ????response = conn.getresponse() ????if response.status == 200: ????????data = json.loads(response.read().decode()) ????????print(f"城市: {data['name']}") ????????print(f"天氣: {data['weather'][0]['description']}") ????????print(f"溫度: {data['main']['temp'] - 273.15:.1f}°C") ?# 轉為攝氏度 ????else: ????????print(f"錯誤: {response.status} - {response.read().decode()}") except Exception as e: ????print(f"發生異常: {e}") finally: ????conn.close() |
8. 與 requests 庫對比
特性 | http.client | requests |
所屬庫 | Python 標準庫(無需安裝) | 第三方庫(需 pip install) |
API 復雜度 | 底層,需要手動處理很多細節 | 高層,簡潔易用 |
請求方法 | request()?結合方法參數 | get(), post(), put()?等 |
響應處理 | 手動解析狀態碼、頭和內容 | 自動解析,提供 json()?方法 |
會話管理 | 需手動管理連接 | 自動管理會話(如 Cookie) |
重定向處理 | 需手動實現 | 自動處理(可配置) |
文件上傳 | 復雜 | 簡單(files?參數) |
9. 常見問題解答
- Q1:如何設置請求超時?
A:在創建連接時指定 timeout?參數,如 HTTPSConnection("example.com", timeout=10)。
- Q2:如何處理 HTTPS 證書驗證?
A:默認驗證證書。若需忽略,使用 context?參數:
import ssl context = ssl._create_unverified_context() conn = http.client.HTTPSConnection("example.com", context=context) |
- Q3:如何發送大文件?
A:使用分塊傳輸(Chunked Transfer),需設置 Transfer-Encoding: chunked?頭,手動分塊發送。
通過這個教程,你應該能夠掌握 http.client?的基本使用方法。在實際項目中,若追求更高的開發效率,推薦使用 requests?庫;若需要底層控制或環境受限(如無第三方庫),則 http.client?是更好的選擇。