深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!

简介: 深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!

🔸 第一部分:requests库的入口

我们从requests库的入口开始,通常我们会使用 requests.get()requests.post() 等方法发送HTTP请求。那么,这些方法背后究竟做了些什么呢?我们从requests.get()方法开始看起:

# requests/__init__.py
def get(url, params=None, **kwargs):
    """Sends a GET request."""
    return request('get', url, params=params, **kwargs)

🔹 requests.get() 实际上是调用了内部的 request() 方法,并将 'get' 作为请求方法传入。让我们进一步深入 request() 方法。


🔸 第二部分:request方法揭秘

requests库中,request() 方法负责构建和发送所有类型的HTTP请求:

# requests/api.py
def request(method, url, **kwargs):
    session = sessions.Session()
    return session.request(method=method, url=url, **kwargs)

🔹 request() 方法创建了一个 Session 对象,然后调用了 session.request()。这意味着实际的请求处理是由 Session 对象完成的。


🔸 第三部分:Session对象的奥秘

Session 对象在requests库中扮演了重要角色。它不仅可以发送请求,还能保存cookie等会话信息:

# requests/sessions.py
class Session(SessionRedirectMixin, RequestHookMixin):
    def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, proxies=None, hooks=None, stream=None, verify=True, cert=None, json=None):
        prep = self.prepare_request(Request(method=method, url=url, headers=headers, files=files, data=data, json=json, params=params, auth=auth, cookies=cookies, hooks=hooks))
        ...
        send_kwargs = {'timeout': timeout, 'allow_redirects': allow_redirects, 'proxies': proxies, 'stream': stream, 'verify': verify, 'cert': cert, 'hooks': hooks}
        ...
        resp = self.send(prep, **send_kwargs)
        return resp

🔹 Session 对象的 request() 方法中首先调用 prepare_request() 方法来构建 Request 对象。然后调用 send() 方法来发送请求。


🔸 第四部分:Request对象的构建

prepare_request() 方法负责构建一个 Request 对象:

# requests/sessions.py
def prepare_request(self, request):
    p = PreparedRequest()
    p.prepare(
        method=request.method.upper(),
        url=request.url,
        files=request.files,
        data=request.data,
        json=request.json,
        headers=request.headers,
        params=request.params,
        auth=request.auth,
        cookies=request.cookies,
        hooks=request.hooks,
    )
    return p

🔹 prepare_request() 方法中调用了 PreparedRequest 类,并通过其 prepare() 方法将请求的各个部分准备好。


🔸 第五部分:PreparedRequest的准备

PreparedRequest 类是用来标准化和准备请求数据的:

# requests/models.py
class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
    def prepare(self, method=None, url=None, headers=None, files=None, data=None, params=None, auth=None, cookies=None, hooks=None, json=None):
        self.prepare_method(method)
        self.prepare_url(url, params)
        self.prepare_headers(headers)
        self.prepare_body(data, files, json)
        self.prepare_auth(auth, url)
        self.prepare_cookies(cookies)
        self.prepare_hooks(hooks)

🔹 PreparedRequest 类的 prepare() 方法中,分别调用了一系列 prepare_* 方法来准备HTTP请求的各个部分,如方法、URL、头信息、请求体等。


🔸 第六部分:发送请求

当请求准备好后,Session 对象的 send() 方法负责实际发送HTTP请求:

# requests/sessions.py
def send(self, request, **kwargs):
    ...
    r = adapter.send(request, **kwargs)
    ...
    return r

🔹 send() 方法中最重要的一步是调用 adapter.send() 方法,这里的 adapterHTTPAdapter 对象,它负责底层的HTTP请求发送。


🔸 第七部分:HTTPAdapter的发送

HTTPAdapter 对象的 send() 方法通过底层库(如urllib3)来实际发送请求:

# requests/adapters.py
class HTTPAdapter(BaseAdapter):
    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
        conn = self.get_connection(request.url, proxies)
        ...
        resp = conn.urlopen(
            method=request.method,
            url=request.url,
            body=request.body,
            headers=request.headers,
            ...
        )
        return self.build_response(request, resp)

🔹 send() 方法通过 get_connection() 方法获取一个连接,然后使用 conn.urlopen() 发送请求,并调用 build_response() 方法构建响应对象。


🔸 第八部分:构建响应

build_response() 方法负责将底层响应对象转换为 requestsResponse 对象:

# requests/adapters.py
def build_response(self, request, resp):
    response = Response()
    response.status_code = resp.status
    response.headers = CaseInsensitiveDict(resp.headers)
    response.raw = resp
    response.url = request.url
    response.request = request
    response.connection = self
    return response

🔹 build_response() 方法中,将底层响应对象的状态码、头信息、URL等信息赋值给 Response 对象,从而完成响应构建。


🔸 总结

🔹 通过以上解析,我们了解了 requests 库从发送请求到接收响应的全过程。从 requests.get() 方法开始,经过 Session 对象的处理、PreparedRequest 的准备、HTTPAdapter 的发送,最终构建 Response 对象。这一系列流程确保了 requests 库能够简洁、高效地处理HTTP请求,让开发者可以专注于业务逻辑的实现。

希望通过这次源码解析,大家对 requests 库有了更深入的理解,能够更好地运用它进行网络请求处理! 🚀

目录
相关文章
|
10月前
|
JSON 监控 API
掌握使用 requests 库发送各种 HTTP 请求和处理 API 响应
本课程全面讲解了使用 Python 的 requests 库进行 API 请求与响应处理,内容涵盖环境搭建、GET 与 POST 请求、参数传递、错误处理、请求头设置及实战项目开发。通过实例教学,学员可掌握基础到高级技巧,并完成天气查询应用等实际项目,适合初学者快速上手网络编程与 API 调用。
937 130
|
机器学习/深度学习 监控 算法
基于mediapipe深度学习的手势数字识别系统python源码
本内容涵盖手势识别算法的相关资料,包括:1. 算法运行效果预览(无水印完整程序);2. 软件版本与配置环境说明,提供Python运行环境安装步骤;3. 部分核心代码,完整版含中文注释及操作视频;4. 算法理论概述,详解Mediapipe框架在手势识别中的应用。Mediapipe采用模块化设计,包含Calculator Graph、Packet和Subgraph等核心组件,支持实时处理任务,广泛应用于虚拟现实、智能监控等领域。
|
10月前
|
人工智能 数据安全/隐私保护 异构计算
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
1526 8
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
|
10月前
|
机器学习/深度学习 数据采集 算法
基于mediapipe深度学习的运动人体姿态提取系统python源码
本内容介绍了基于Mediapipe的人体姿态提取算法。包含算法运行效果图、软件版本说明、核心代码及详细理论解析。Mediapipe通过预训练模型检测人体关键点,并利用部分亲和场(PAFs)构建姿态骨架,具有模块化架构,支持高效灵活的数据处理流程。
|
10月前
|
小程序 PHP 图形学
热门小游戏源码(Python+PHP)下载-微信小程序游戏源码Unity发实战指南​
本文详解如何结合Python、PHP与Unity开发并部署小游戏至微信小程序。涵盖技术选型、Pygame实战、PHP后端对接、Unity转换适配及性能优化,提供从原型到发布的完整指南,助力开发者快速上手并发布游戏。
|
12月前
|
算法 数据可视化 数据挖掘
基于EM期望最大化算法的GMM参数估计与三维数据分类系统python源码
本内容展示了基于EM算法的高斯混合模型(GMM)聚类实现,包含完整Python代码、运行效果图及理论解析。程序使用三维数据进行演示,涵盖误差计算、模型参数更新、结果可视化等关键步骤,并附有详细注释与操作视频,适合学习EM算法与GMM模型的原理及应用。
|
12月前
|
API 数据安全/隐私保护 开发者
企业微信自动加好友软件,导入手机号批量添加微信好友,python版本源码分享
代码展示了企业微信官方API的合规使用方式,包括获取access_token、查询部门列表和创建用户等功能
|
11月前
|
并行计算 算法 Java
Python3解释器深度解析与实战教程:从源码到性能优化的全路径探索
Python解释器不止CPython,还包括PyPy、MicroPython、GraalVM等,各具特色,适用于不同场景。本文深入解析Python解释器的工作原理、内存管理机制、GIL限制及其优化策略,并介绍性能调优工具链及未来发展方向,助力开发者提升Python应用性能。
590 0
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
294 19
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
301 10

推荐镜像

更多