Python HTTP 请求类标准封装与调用指南

键盘旁的猫
键盘旁的猫
发布时间:2026-10-12| 1人浏览过
原创

针对常规 HTTP 请求中重复编写 Header、鉴权与参数拼接的代码痛点,本文提供基于 Python 标准库的网络请求类封装方案。该类支持 GET/POST 方法切换、Base64 基础认证、Cookie 注入及自定义请求头,并内置响应状态码、Headers、源码解析等快捷访问方法,可显著降低接口调试与轻量级数据抓取的样板代码量。

设计目标与核心逻辑

原始代码旨在简化 HTTP 交互流程,将 URL 构造、类型区分(GET/POST)、鉴权处理(Basic Auth/Cookie)与响应解析集中到一个 Class 中。以下为适配现代 Python 环境的稳定实现版本,修复了原稿中字典键未加引号导致的运行时异常,并将底层模块迁移至 Python 3 标准库以保障可用性。

完整封装代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import urllib.request
import urllib.parse
import urllib.error
import time

class SendRequest:
    '''
    用于封装 HTTP 请求,支持设置认证方式、请求类型、自定义 Headers,
    并提供响应信息(源码、状态码、Headers字典、Cookie等)的快捷访问接口。
    '''
    def __init__(self, url, data=None, req_type='GET', auth=None, user=None, password=None, cookie=None, **headers):
        self.url = url
        self.data = data
        self.req_type = req_type.upper()
        self.auth = auth
        self.user = user
        self.password = password
        self.cookie = cookie
        # 安全获取自定义Header,避免键名缺失引号报错
        self.referer = headers.get('referer')
        self.user_agent = headers.get('user-agent')
        
        self.setup_request()
        self.send_request()

    def setup_request(self):
        if not self.url:
            raise ValueError("The url should not be empty!")

        # 拼接GET请求URL或准备POST数据
        if self.req_type == 'POST':
            post_data = urllib.parse.urlencode(self.data).encode('utf-8') if isinstance(self.data, dict) else self.data.encode('utf-8')
            self.Req = urllib.request.Request(self.url, data=post_data)
        elif self.req_type == 'GET':
            query_str = urllib.parse.urlencode(self.data) if self.data else ''
            final_url = f"{self.url}?{query_str}" if query_str else self.url
            self.Req = urllib.request.Request(final_url)
        else:
            print('The http request type NOT supported!')

        # 处理基础认证 (Basic Auth)
        if self.auth == 'base':
            if not self.user or not self.password:
                raise ValueError("The user or password was not given!")
            credentials = base64.b64encode(f"{self.user}:{self.password}".encode()).decode().strip()
            self.Req.add_header("Authorization", f"Basic {credentials}")
        elif self.auth == 'cookie':
            if not self.cookie:
                raise ValueError("The cookie was not given!")
            self.Req.add_header("Cookie", self.cookie)

        # 附加通用Header
        if self.referer:
            self.Req.add_header('Referer', self.referer)
        if self.user_agent:
            self.Req.add_header('User-Agent', self.user_agent)

    def send_request(self):
        try:
            self.Res = urllib.request.urlopen(self.Req)
            self.source = self.Res.read().decode('utf-8', errors='ignore')
            self.goal_url = self.Res.geturl()
            self.code = self.Res.getcode()
            self.head_dict = dict(self.Res.info())
            self.Res.close()
        except urllib.error.HTTPError as e:
            self.code = e.code
            print(f"HTTP Error: {e.reason}")
        except Exception as e:
            print(f"Network Error: {e}")
            self.code = None

    def get_code(self): return self.code
    def get_url(self): return self.goal_url
    def get_source(self): return self.source
    def get_header_info(self): return self.head_dict

    def get_cookie(self):
        return self.head_dict.get('set-cookie') if self.head_dict else None
    def get_content_type(self):
        return self.head_dict.get('content-type') if self.head_dict else None
    def get_expires_time(self):
        return self.head_dict.get('expires') if self.head_dict else None
    def get_server_name(self):
        return self.head_dict.get('server') if self.head_dict else None

if __name__ == '__main__':
    t_start = time.time()
    # 测试示例:基础GET请求
    rs = SendRequest('http://httpbin.org/get', headers={'user-agent': 'TestBot/1.0'})
    
    print(f'[耗时] {time.time() - t_start:.3f}s')
    print(f'[状态码] {rs.get_code()}')
    print(f'[响应URL] {rs.get_url()}')
    print(f'[响应长度] {len(rs.get_source())}')
    print(f'[服务器] {rs.get_server_name()}')
    rs = None

第1步:初始化与参数映射

通过构造函数接收目标地址、载荷、请求方式及鉴权凭证。代码内部会将字典格式的参数统一转换为 URL 编码字符串,并通过 **headers 透传额外标识(如来源页伪装与客户端指纹)。初始化结束后立即触发请求构建与发送,确保实例化即可直接获得响应对象。

第2步:请求头组装与认证拦截

根据 req_type 动态选择 GET 拼接参数或 POST 提交表单数据。当指定 auth='base' 时,自动对账号密码进行 Base64 编码并注入 Authorization 字段;若需携带会话凭证,可通过 cookie 参数写入。所有前置校验均会抛出明确异常,防止无效请求发出。

第3步:执行发送与结果提取

调用标准库发起连接后,程序同步读取响应体并解码为文本,同时捕获重定向后的最终地址。内置的 getter 方法可直接返回状态码、Headers 映射表或特定字段(如 set-cookie、server)。示例代码演示了单次 GET 请求的调用链路,控制台将按序输出耗时、状态码与关键元数据,验证完成即可复用至其他接口。

部署与兼容性提醒

本方案严格遵循 Python 3 语法规范运行。若您的项目仍停留在旧版环境,请将顶层导入恢复为对应平台的 urllib 分支,并调整 print 语句与字典遍历方式。涉及敏感凭证传输时,务必配合 HTTPS 使用,且强烈建议在复杂业务场景下评估是否接入成熟的第三方 HTTP 客户端以降低长期维护成本。

以上就是 Python HTTP 请求简单封装的详细内容,更多关于 Python 网络请求与标准库调用的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。