Requests源码分析:面试考察角度梳理

发布于:2025-06-30 ⋅ 阅读:(13) ⋅ 点赞:(0)

简单描述执行流程 🌟

Q:能简单描述一下发送一个requests.get(url)请求时,在requests库内部的主要执行流程吗?(从调用get方法到收到响应)

  1. 入口委托: get() 方法内部调用 requests.request('GET', url)
  2. Session 接管: request() 方法会获取或隐式创建一个 Session 对象,并调用其 request() 方法。Session 是核心,负责管理 Cookies、连接池复用和全局配置。
  3. 请求准备: Session 将传入的参数(URL、headers、params 等)合并、编码,构建成一个标准的 PreparedRequest 对象
  4. 适配器与发送: Session 根据 URL 协议 (http/https) 选择对应的 HTTPAdapterHTTPAdapter 利用底层的 urllib3 连接池 获取一个到目标服务器的连接(或新建),然后发送 PreparedRequest
  5. 处理响应:
    • 处理重定向: 如果响应是重定向 (3xx) 且允许 (allow_redirects=True),会自动处理重定向链,直到获得最终响应。
    • 构建响应:urllib3 的原始响应封装成 requests.Response 对象,设置状态码、头信息、Cookies (更新 Session)、历史记录等。
  6. 返回结果: 最终 Response 对象返回给调用者。
  7. 释放资源: 通过with requests.Session() as request: 显式使用上下文管理器,确保在退出时自动调用 request.close()释放底层的 urllib3 连接池资源,避免连接泄漏。

Session对象的作用

Q:Session 对象 (requests.Session) 的主要作用是什么?它与直接调用 requests.get/post 在底层实现上有什么关键区别

Session 是跨请求的持久化上下文管理器,核心解决 连接复用状态保持配置继承 三大问题。

  • 连接池复用:
    • 底层通过 urllib3.PoolManager 复用 TCP 连接(尤其对同一主机发起多次请求时)
    • 避免重复 TCP 握手/TLS 协商,显著提升性能
  • 状态保持:
    • 自动处理 Cookies:响应 Cookies 自动存储,后续请求自动携带
    • 持久化认证:auth 参数在会话内持续有效
  • 配置继承:
    • 统一设置全局参数
    • 支持全局 proxies, hooks, stream 等配置

注册适配器逻辑

Q:Session 如何通过 mount() 方法注册适配器?适配器与 URL 前缀的映射规则是什么?

  • 创建 Session 对象时,自动注册默认的httpshttp适配器。
    在这里插入图片描述
  • mount根据适配器的前缀长度来按序存储,前缀长的放前面,为了保证获取适配器时能按最长前缀优先匹配。
    在这里插入图片描述
  • 由于按序存储,获取adapter时,前缀匹配成功就直接返回,能获取到匹配的最长前缀适配器。
    在这里插入图片描述

Ses


网站公告

今日签到

点亮在社区的每一天
去签到