Python实现简单封装网络请求的示例详解

2025-09-24 00:50

本文主要是介绍Python实现简单封装网络请求的示例详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...

安装依赖

在开始使用前,需先安装工具依赖的第三方库。打开终端(命令行),执行以下命令:

pip install requests tenacity

核心功能说明

1. 类与方法概览

类/方法功能描述
ApiResponse 类响应数据包装类,提供状态js检查、数据获取等便捷方法
NetHelper 类核心请求封装类,支持初始化配置、多 HTTP 方法调用
get()/post()/put()/delete()对外暴露的快捷方法,分别对应 GET/POST/PUT/DELETE 请求

2.NetHelper类初始化参数

初始化 NetHelper 实例时,需传入以下参数(均为可选,有默认值):

参数名类型说明
base_urlstr基础 URL(如 https://api.example.com),请求路径会自动拼接至此 URL
headersDict[str, str]默认请求头(会被单次请求的头覆盖)
timeoutint请求超时时间(秒,默认 15 秒)
verify_sslbool是否验证 SSL 证书(生产环境建议设为 True,测试环境可设为 False)

3.ApiResponse类属性与方法

ApiResponse 用于包装接口响应数据,提供以下核心功能:

属性/方法类型说明
dataAny响应体解析后的数据(jsON 自动转为字典,非 JSON 为文本/二进制)
status_codeintHTTP 状态码(如 200、404)
errorOptional[str]错误信息(仅当状态码非 2xx 或发生异常时存在)
is_success()bool检查请求是否成功(状态码 2xx 且无错误信息时返回 True)

使用实例

步骤 1:导入工具类

from net_helper import NetHelper, ApiResponse  # 假设工具保存为 net_helper.py

步骤 2:初始化NetHelper实例

请求头和基础 URL 配置:

# 初始化 NetHelper
client = NetHelper(
    base_url="https://com.text.com",
    headers={
        "Accept": "application/json, text/plain, */*",
        "Content-Type": "application/json;charset=UTF-8",
    },
)

步骤 3:发送登录请求

使用 post() 方法发送 POST 请求,传入请求体和参数:

response = client.post(
    url="/login",
    json={
        "name": "bin",
        "pwd": "123456",
    }
)

步骤 4:处理响应结果

根据 ApiResponse 的属性判断请求是否成功,并获取数据:

if response.is_success():
    print("登录成功!")
    print("响应数据:", response.data)
    print("状态码:", response.status_code)
else:
    print(f"登录失败!错误信息: {response.error}")
    print("状态码:", response.status_code)
    print("原始响应:", 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",
    China编程datefmt="%Y-%m-%d %H:%M:%S"
)
logger = logging.getLogger(__name__)


class ApiResponse:
    """API响应包装类"""
    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,
   编程China编程     json: Optional[Union[Dict[str, Any], str]] = None,
        data: Optional[Union[Dict[str, Any], str, bytes]] = None,
        params: Optional[Dict[str, Any]] = None
    ) -> ApiResponse:
        """内部请求方法"""
        # 拼接完整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("请求参数:")
                print(jsonlib.dumps(params, ensure_ascii=False, indent=2))
            if json:
                print("请求JSON数据:")
                print(jsonlib.dumps(json, ensure_ascii=False, indent=2))
            if data:
                print("请求表单数据:")
                if isinstance(data, (dict, list)):
                    print(jsonlib.dumps(data, ensure_ascii=False, indent=2))
                else:
                    print(data)
            
            # 发送请求
            response = requests.request(
                method=method.upper(),
                url=full_url,
                headers=merged_headers,
                json=json,
                data=data,
                params=params,
                timeoutphp=self.timeout,
                verify=self.verify_ssl
  javascript          )

            # 解析响应
            try:
                result_data = response.json()
            except ValueError:
                result_data = response.text if response.encoding else response.content

            print("响应数据:")
            print(jsonlib.dumps(result_data, ensure_ascii=False, indent=2))
            
            # 检查HTTP状态码
            if 200 <= response.status_code < 300:
                return ApiResponse(result_data, response.status_code)
            else:
                error_msg = f"HTTP错误: 状态码 {response.status_code}"
                logger.error(f"{error_msg}, 响应: {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)

到此这篇关于Python实现简单封装网络请求的示例详解的文章就介绍到这了,更多相关Python封装网络请求内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Python实现简单封装网络请求的示例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155990

相关文章

一个Java的main方法在JVM中的执行流程示例详解

《一个Java的main方法在JVM中的执行流程示例详解》main方法是Java程序的入口点,程序从这里开始执行,:本文主要介绍一个Java的main方法在JVM中执行流程的相关资料,文中通过代码... 目录第一阶段:加载 (Loading)第二阶段:链接 (Linking)第三阶段:初始化 (Initia

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

java时区时间转为UTC的代码示例和详细解释

《java时区时间转为UTC的代码示例和详细解释》作为一名经验丰富的开发者,我经常被问到如何将Java中的时间转换为UTC时间,:本文主要介绍java时区时间转为UTC的代码示例和详细解释,文中通... 目录前言步骤一:导入必要的Java包步骤二:获取指定时区的时间步骤三:将指定时区的时间转换为UTC时间步

Java 日志中 Marker 的使用示例详解

《Java日志中Marker的使用示例详解》Marker是SLF4J(以及Logback、Log4j2)提供的一个接口,它本质上是一个命名对象,你可以把它想象成一个可以附加到日志语句上的标签或戳... 目录什么是Marker?为什么使用Markejavascriptr?1. 精细化的过滤2. 触发特定操作3

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

Spring定时任务之fixedRateString的实现示例

《Spring定时任务之fixedRateString的实现示例》本文主要介绍了Spring定时任务之fixedRateString的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录从毫秒到 Duration:为何要改变?核心:Java.time.Duration.parse

一文详解MySQL索引(六张图彻底搞懂)

《一文详解MySQL索引(六张图彻底搞懂)》MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度,:本文主要介绍MySQL索引的相关资料,文中通过代码介绍的... 目录一、什么是索引?为什么需要索引?二、索引该用哪种数据结构?1. 哈希表2. 跳表3. 二叉排序树4.

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的

Java中实现对象的拷贝案例讲解

《Java中实现对象的拷贝案例讲解》Java对象拷贝分为浅拷贝(复制值及引用地址)和深拷贝(递归复制所有引用对象),常用方法包括Object.clone()、序列化及JSON转换,需处理循环引用问题,... 目录对象的拷贝简介浅拷贝和深拷贝浅拷贝深拷贝深拷贝和循环引用总结对象的拷贝简介对象的拷贝,把一个