Python實(shí)現(xiàn)簡單封裝網(wǎng)絡(luò)請求的示例詳解
安裝依賴
在開始使用前,需先安裝工具依賴的第三方庫。打開終端(命令行),執(zhí)行以下命令:
pip install requests tenacity
核心功能說明
1. 類與方法概覽
| 類/方法 | 功能描述 |
|---|---|
| ApiResponse 類 | 響應(yīng)數(shù)據(jù)包裝類,提供狀態(tài)檢查、數(shù)據(jù)獲取等便捷方法 |
| NetHelper 類 | 核心請求封裝類,支持初始化配置、多 HTTP 方法調(diào)用 |
| get()/post()/put()/delete() | 對外暴露的快捷方法,分別對應(yīng) GET/POST/PUT/DELETE 請求 |
2.NetHelper類初始化參數(shù)
初始化 NetHelper 實(shí)例時,需傳入以下參數(shù)(均為可選,有默認(rèn)值):
| 參數(shù)名 | 類型 | 說明 |
|---|---|---|
| base_url | str | 基礎(chǔ) URL(如 https://api.example.com),請求路徑會自動拼接至此 URL |
| headers | Dict[str, str] | 默認(rèn)請求頭(會被單次請求的頭覆蓋) |
| timeout | int | 請求超時時間(秒,默認(rèn) 15 秒) |
| verify_ssl | bool | 是否驗(yàn)證 SSL 證書(生產(chǎn)環(huán)境建議設(shè)為 True,測試環(huán)境可設(shè)為 False) |
3.ApiResponse類屬性與方法
ApiResponse 用于包裝接口響應(yīng)數(shù)據(jù),提供以下核心功能:
| 屬性/方法 | 類型 | 說明 |
|---|---|---|
| data | Any | 響應(yīng)體解析后的數(shù)據(jù)(JSON 自動轉(zhuǎn)為字典,非 JSON 為文本/二進(jìn)制) |
| status_code | int | HTTP 狀態(tài)碼(如 200、404) |
| error | Optional[str] | 錯誤信息(僅當(dāng)狀態(tài)碼非 2xx 或發(fā)生異常時存在) |
| is_success() | bool | 檢查請求是否成功(狀態(tài)碼 2xx 且無錯誤信息時返回 True) |
使用實(shí)例
步驟 1:導(dǎo)入工具類
from net_helper import NetHelper, ApiResponse # 假設(shè)工具保存為 net_helper.py
步驟 2:初始化NetHelper實(shí)例
請求頭和基礎(chǔ) URL 配置:
# 初始化 NetHelper
client = NetHelper(
base_url="https://com.text.com",
headers={
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=UTF-8",
},
)
步驟 3:發(fā)送登錄請求
使用 post() 方法發(fā)送 POST 請求,傳入請求體和參數(shù):
response = client.post(
url="/login",
json={
"name": "bin",
"pwd": "123456",
}
)
步驟 4:處理響應(yīng)結(jié)果
根據(jù) ApiResponse 的屬性判斷請求是否成功,并獲取數(shù)據(jù):
if response.is_success():
print("登錄成功!")
print("響應(yīng)數(shù)據(jù):", response.data)
print("狀態(tài)碼:", response.status_code)
else:
print(f"登錄失??!錯誤信息: {response.error}")
print("狀態(tài)碼:", response.status_code)
print("原始響應(yīng):", response.data)
五、源碼
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import json as jsonlib
from typing import Dict, Optional, Union, Any
import requests
from tenacity import (
retry,
stop_after_attempt,
wait_exponential,
retry_if_exception_type,
)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
logger = logging.getLogger(__name__)
class ApiResponse:
"""API響應(yīng)包裝類"""
def __init__(self, data: Any, status_code: int = 200, error: Optional[str] = None):
self.data = data
self.status_code = status_code
self.error = error
self.message = data.get('message', '') if isinstance(data, dict) else ''
def is_success(self) -> bool:
"""檢查請求是否成功"""
return 200 <= self.status_code < 300 and self.error is None
class NetHelper:
def __init__(self,
base_url: str,
headers: Optional[Dict[str, str]],
timeout: int = 15,
verify_ssl: bool = True):
self.base_url = base_url.rstrip("/")
self.default_headers = headers
self.timeout = timeout
self.verify_ssl = verify_ssl
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10),
retry=retry_if_exception_type((
requests.exceptions.ConnectionError,
requests.exceptions.Timeout
)),
reraise=True
)
def _send_request(
self,
method: str = "GET",
url: str = "",
headers: Optional[Dict[str, str]] = None,
json: Optional[Union[Dict[str, Any], str]] = None,
data: Optional[Union[Dict[str, Any], str, bytes]] = None,
params: Optional[Dict[str, Any]] = None
) -> ApiResponse:
"""內(nèi)部請求方法"""
# 拼接完整URL
full_url = f"{self.base_url}/{url.lstrip('/')}"
# 合并請求頭
merged_headers = {**self.default_headers, **(headers or {})}
# 移除空值頭
merged_headers = {k: v for k, v in merged_headers.items() if v is not None}
try:
# 打印請求體
print("請求方法:", method.upper())
print("請求URL:", full_url)
if params:
print("請求參數(shù):")
print(jsonlib.dumps(params, ensure_ascii=False, indent=2))
if json:
print("請求JSON數(shù)據(jù):")
print(jsonlib.dumps(json, ensure_ascii=False, indent=2))
if data:
print("請求表單數(shù)據(jù):")
if isinstance(data, (dict, list)):
print(jsonlib.dumps(data, ensure_ascii=False, indent=2))
else:
print(data)
# 發(fā)送請求
response = requests.request(
method=method.upper(),
url=full_url,
headers=merged_headers,
json=json,
data=data,
params=params,
timeout=self.timeout,
verify=self.verify_ssl
)
# 解析響應(yīng)
try:
result_data = response.json()
except ValueError:
result_data = response.text if response.encoding else response.content
print("響應(yīng)數(shù)據(jù):")
print(jsonlib.dumps(result_data, ensure_ascii=False, indent=2))
# 檢查HTTP狀態(tài)碼
if 200 <= response.status_code < 300:
return ApiResponse(result_data, response.status_code)
else:
error_msg = f"HTTP錯誤: 狀態(tài)碼 {response.status_code}"
logger.error(f"{error_msg}, 響應(yīng): {result_data}")
return ApiResponse(result_data, response.status_code, error_msg)
except requests.exceptions.ConnectionError as e:
logger.error(f"連接失敗: 無法連接到 {full_url}")
return ApiResponse({}, 0, str(e))
except requests.exceptions.Timeout as e:
logger.error(f"請求超時: 超過 {self.timeout} 秒")
return ApiResponse({}, 0, str(e))
except Exception as e:
logger.error(f"未知錯誤: {str(e)}")
return ApiResponse({}, 0, str(e))
def post(self, url: str, data: Optional[Any] = None, params: Optional[Dict[str, Any]] = None) -> ApiResponse:
return self._send_request(method="POST", url=url, json=data, params=params)
def get(self, url: str, params: Optional[Dict[str, Any]] = None) -> ApiResponse:
return self._send_request(method="GET", url=url, params=params)
def put(self, url: str, data: Optional[Any] = None, params: Optional[Dict[str, Any]] = None) -> ApiResponse:
return self._send_request(method="PUT", url=url, json=data, params=params)
def delete(self, url: str, params: Optional[Dict[str, Any]] = None) -> ApiResponse:
return self._send_request(method="DELETE", url=url, params=params)
到此這篇關(guān)于Python實(shí)現(xiàn)簡單封裝網(wǎng)絡(luò)請求的示例詳解的文章就介紹到這了,更多相關(guān)Python封裝網(wǎng)絡(luò)請求內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 實(shí)現(xiàn)PS濾鏡中的徑向模糊特效
這篇文章主要介紹了Python 實(shí)現(xiàn) PS 濾鏡中的徑向模糊特效,幫助大家更好的利用python處理圖片,感興趣的朋友可以了解下2020-12-12
淺談flask中的before_request與after_request
這篇文章主要介紹了淺談flask中的before_request與after_request,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-01-01
Python實(shí)現(xiàn)以時間換空間的緩存替換算法
緩存是指可以進(jìn)行高速數(shù)據(jù)交換的存儲器,它先于內(nèi)存與CPU交換數(shù)據(jù),因此速度很快。緩存就是把一些數(shù)據(jù)暫時存放于某些地方,可能是內(nèi)存,也有可能硬盤。下面給大家介紹Python實(shí)現(xiàn)以時間換空間的緩存替換算法,需要的朋友參考下2016-02-02
Python查看Tensor尺寸及查看數(shù)據(jù)類型的實(shí)現(xiàn)
這篇文章主要介紹了Python查看Tensor尺寸及查看數(shù)據(jù)類型的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
Python 中使用 Selenium 單擊網(wǎng)頁按鈕功能
Selenium是一個用于測試網(wǎng)站的自動化測試工具,支持各種瀏覽器包括Chrome、Firefox、Safari等主流界面瀏覽器,同時也支持phantomJS無界面瀏覽器,本篇文章將介紹如何在 Python 中使用 selenium 單擊網(wǎng)頁上的按鈕,感興趣的朋友一起看看吧2023-11-11
python正則表達(dá)中的re庫常用方法總結(jié)
這篇文章主要介紹了python正則表達(dá)中的re庫常用方法總結(jié)文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-08-08
Python遞歸調(diào)用實(shí)現(xiàn)數(shù)字累加的代碼
今天小編就為大家分享一篇Python遞歸調(diào)用實(shí)現(xiàn)數(shù)字累加的代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02

