python HTTP请求同时返回为JSON的异常处理

近期某个同事要定期统计当前某个设备的运行状态的情况,按照正常逻辑进行编写了程序,调试验证后可正常使用,但是遇到一个问题:

在调用第三方的接口时,返回504超时导致JSON解析失败的情况,即出现了非JSON响应,故计划增加超时重试、响应格式验证 来规避此问题。

一、封装完整HTTP请求异常处理函数
1、确定函数封装的主要功能

支持常用的GET和POST、超时控制、自动重试

捕获异常分类,解决异常类导入的问题(非JSON返回文案提示,超时记录并重试,错误状态码提示、请求异常重试)

校验HTTP状态码(通过raise_for_status(),2XX为成功,否则跑出HTTPError)
2、封装函数的实现

python 复制代码
import time,requests
from requests.exceptions import (RequestException,Timeout,HTTPError)
#兼容原生json解析错误
from json.decoder import  JSONDecodeError as JsonLibJSONDecodeError

def http_request(url:str,method:str = "POST",params: dict = None,data: dict = None,headers: dict = None,timeout :int = 10,max_retries : int =3,retry_delay: float = 2)->dict:
    params = params or {}
    data  =data or {}
    headers =headers or {}

    for retry in range(max_retries):
        try:
        	#程序主体部分
            if method.upper() == "GET":
                response = requests.get(
                    url=url,
                    data=params,
                    headers=headers,
                    timeout=timeout
                )
            elif method.upper() == "POST":
                response = requests.post(
                    url=url,
                    data=params,
                    json=data,  
                    headers=headers,
                    timeout=timeout
                )
            else:
                return {
                    "success": False,
                    "data": None,
                    "message": f"不支持的请求方法:{method}"
                }

            # 校验HTTP状态码(2xx为成功,否则抛出HTTPError)
            response.raise_for_status()

            # 尝试解析JSON响应
            try:
                response_data = response.json()
            except JsonLibJSONDecodeError:
                # 若响应为空或非JSON,返回原始文本(可选)
                response_data = response.text
                return {
                    "success": True,
                    "data": response_data,
                    "message": "响应非JSON格式,返回原始文本",
                    "response": response
                }

            # 请求成功,返回结果
            return {
                "success": True,
                "data": response_data,
                "message": "请求成功",
                "response": response
            }
        except Timeout:
            #超时异常,记录日志并重试
            error_msg = f"⚠️请求超时,第{retry+1}/{max_retries}次重试"
            print(f"【ERROR】{error_msg}")
            if retry < max_retries:
                time.sleep(retry_delay)
            else:
                return {"success":False,"data":None,"message":f"请求超时,已重试{max_retries}次:{url}"}
        except HTTPError as e:
            #HTTP状态错误(如504、403。。。)
            error_msg = f"HTTP错误:{e.response.status_code}--{e.response.text}"
            print(f"【ERROR】{error_msg}")
            return {"success":False,"data":None,"message": error_msg,"response":e.response}

        except RequestException as e:
            # 其他请求异常(连接失败、DNS解析错误等)
            error_msg = f"请求异常:{str(e)}"
            print(f"[ERROR] {error_msg}")
            if retry < max_retries:
                time.sleep(retry_delay)
            else:
                return {
                    "success": False,
                    "data": None,
                    "message": f"请求失败,已重试{max_retries}次:{error_msg}"
                }

    return {
        "success": False,
        "data": None,
        "message": f"请求失败,超出最大重试次数{max_retries}"
    }```


二、编写demo,进行封装函数的验证
```python
def demo(environment):
    """
    功能:验证异常处理程序是否可用
    :return:
    """
    timeline_start_time = deal_time.get_LondonTime(BJ_start_time)
    timeline_end_time = deal_time.get_LondonTime(BJ_end_time)
    query = {
    #此处填写调用接口的参数
    }
    datas = json.dumps(query)
    headers = {
        "X-AUTH-SOURCE": "SSO",
        "Cookie": deal_token.get_token(environment),
        "Content-Type": "application/json; charset=UTF-8",
        'Connection': 'close'
    }#请根据实际情况进行修改
    if environment == "test":
        select_url = "对应的url"
    if environment == "online":
        select_url = "对应的url"
    response = http_request(url=select_url, method="POST", params =datas, headers=headers, timeout=10,max_retries =3,retry_delay =2)

    if response["data"]["code"] !=0:
    	#针对token经常过期进行兜底
        deal_token.update_token(environment)#该函数根据实际情况进行实现
        headers = {
            "X-AUTH-SOURCE": "SSO",
            "Cookie": deal_token.get_token(environment),
            "Content-Type": "application/json; charset=UTF-8",
            'Connection': 'close'
        }
        response = http_request(url=select_url, method="POST", params =datas, headers=headers, timeout=10,max_retries =3,retry_delay =2)
    data = response["data"]["data"]
    return data 

1、验证方式一:通过写错误的url验证HTTP状态码

验证返回结果如下:

2、验证方式二:通过缩短超时时间,验证超时

3、验证方式三:正常请求

通过执行demo,未发生异常时,运行正常。

相关推荐
hhzz2 小时前
Python大数据实战(十六):音乐推荐系统——基于协同过滤算法构建个性化歌单引擎
大数据·人工智能·python·数据挖掘·数据分析
耍酷的魔镜3 小时前
核心设计理念:5W2H、JSON-LD 与通用知识图谱
人工智能·json·知识图谱
SunnyDays10113 小时前
Python PDF 转 Markdown 详解(转换整个文档,特定页面,表格,扫描 PDF)
python·pdf 转 markdown·pdf 转 md·扫描 pdf 转 md·pdf 表格转 md
自信的未来3 小时前
JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
java·前端·json
2601_954706493 小时前
云手机 API 自动化实战:Python 批量控机、挂机脚本完整实现
python·智能手机·自动化
华清远见成都中心4 小时前
物联网通信协议对比:MQTT、CoAP、HTTP到底该怎么选
物联网·网络协议·http
墨神谕5 小时前
JSON-RPC 2.0
网络协议·rpc·json
Alan_6917 小时前
聊聊 Swagger/Postman/Apifox 的真实选型与 Python 项目实战
python·测试工具·postman
智慧物业老杨8 小时前
物业绿化数智化权责管控方案:基于工单平台的双层权限追溯模块落地实践
python
Metaphor6928 小时前
使用 Python 在 Word 文档中添加批注
python·word