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

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础