深入理解Requests库中的请求与响应模型

深入理解Requests库中的请求与响应模型

【免费下载链接】Tutorial-Codebase-Knowledge Turns Codebase into Easy Tutorial with AI 【免费下载链接】Tutorial-Codebase-Knowledge 项目地址: https://gitcode.com/gh_mirrors/tu/Tutorial-Codebase-Knowledge

前言

在Python的网络请求库中,Requests库以其简洁优雅的API设计赢得了广大开发者的青睐。本文将深入剖析Requests库的核心组成部分——请求与响应模型,帮助开发者更好地理解和使用这个强大的工具。

请求与响应模型的基本概念

为什么需要模型?

想象一下在餐厅点餐的过程:你不会只是简单地说"我要食物",而是会提供具体的细节——"一份大号意大利辣香肠披萨,送到主街123号"。餐厅会根据这些信息准备食物,并在送达时附带收据。

网络请求同样遵循这样的模式。你需要明确告诉服务器:

  • 你想要什么(URL路径,如/getpost
  • 如何交互(请求方法,如GET或POST)
  • 额外的细节(如请求头或发送的数据)

服务器则会回复:

  • 请求是否成功(状态码,如200 OK或404 Not Found)
  • 关于回复的信息(头部,如内容类型)
  • 你请求的实际内容(如HTML或JSON)

Requests库使用专门的Python对象来组织这些信息,这就是请求与响应模型

核心组件解析

1. Request对象:你的订单

Request对象代表你想要发送的请求的基本意图。它包含:

  • 目标URL
  • 请求方法(GET、POST等)
  • 需要添加的请求头
  • 要发送的数据

虽然在使用简单的函数式API时你通常不会直接创建这个对象,但Requests库会在内部为你处理。

类比:就像你在点餐单上写下"大号披萨,意大利辣香肠,额外芝士"。

2. PreparedRequest对象:准备好的餐盘

这是请求的最终版本,已经准备好发送。Requests库会:

  1. 获取初始的Request对象
  2. 处理它(编码数据、应用cookie、添加默认头如User-Agent)
  3. 准备通过网络发送

它包含了将要发送的确切字节和最终细节,这主要是一个内部处理步骤。

类比:厨房根据你的点餐单制作披萨,装盒,添加餐巾纸和饮料,将所有东西放在托盘上准备交给配送员。

3. Response对象:送达的餐食

这个对象代表服务器在收到PreparedRequest后的回复。它包含:

  • 状态码(订单是否成功?)
  • 响应头(这是什么类型的食物?如何包装的?)
  • 实际内容(披萨本身!)

这是你通常会直接与之交互的对象。

类比:配送员将装有披萨和收据的托盘交给你。你检查收据(status_codeheaders)然后享用披萨(content)。

深入Response对象

让我们通过一个实际例子来探索Response对象的各个有用部分:

import requests

url = 'https://httpbin.org/get'
response = requests.get(url)

# 1. 状态码:请求是否成功?
print(f"状态码: {response.status_code}")  # 数字如200(成功)或404(未找到)
print(f"是否成功(状态码<400)? {response.ok}")  # 布尔值True/False

# 2. 响应头:关于响应的信息
print(f"\n响应头(Content-Type): {response.headers['Content-Type']}")
print("所有头信息:")
for key, value in response.headers.items():
    print(f"  {key}: {value}")

# 3. 响应内容(正文):实际数据!
#    - 作为文本(使用猜测的编码解码):
print("\n响应文本(前100个字符):")
print(response.text[:100])

#    - 作为原始字节(对非文本内容如图片很有用):
print("\n响应内容(字节,前20个):")
print(response.content[:20])

# 4. JSON辅助方法:如果内容是JSON
json_url = 'https://httpbin.org/json'
json_response = requests.get(json_url)
if json_response.ok and 'application/json' in json_response.headers.get('Content-Type', ''):
    try:
        data = json_response.json()  # 将JSON解码为Python字典/列表
        print("解码后的JSON数据:")
        print(data)
    except requests.exceptions.JSONDecodeError:
        print("响应不是有效的JSON。")

Response对象的关键属性

  1. status_code:标准的HTTP状态码数字。200表示"OK",404表示"未找到"。
  2. ok:一个快速的布尔检查。如果状态码小于400(表示成功或重定向)则为True,对于错误(4xx或5xx代码)则为False。
  3. headers:一个类似字典的对象,包含服务器发送的响应头(如Content-Type、Date、Server)。它是大小写不敏感的。
  4. text:将响应体解码为字符串。Requests会尝试根据头部猜测正确的文本编码,或者根据内容本身进行猜测。适用于HTML、纯文本等。
  5. content:作为原始字节的响应体,与从服务器接收的完全一致。适用于图片、下载或当你需要精确控制解码时。
  6. json():一个便捷的方法,尝试将response.text解析为JSON并返回Python字典或列表。如果内容不是有效的JSON,则会引发错误。

内部工作原理:从请求到响应

当你调用requests.get(url)时,幕后发生了以下过程(简化版):

  1. 创建Request:Requests创建一个包含方法('GET')、url和你提供的其他参数(如headers或params)的Request对象。
  2. 准备Request:这个Request对象被传递给准备步骤,变成PreparedRequest。这包括:
    • 合并会话级设置(如来自Session的默认头或cookie)
    • 编码参数(params)
    • 编码正文(data或json)
    • 处理认证(auth)
    • 添加标准头(如User-Agent、Accept-Encoding)
    • 解析最终URL
  3. 发送PreparedRequest:包含确切字节和头的PreparedRequest被交给传输适配器,处理实际的网络通信。
  4. 接收回复:传输适配器等待服务器的回复(状态行、头、正文)。
  5. 构建Response:适配器使用原始回复数据构建你将收到的Response对象。它解析状态码、头,并使原始内容可用。
  6. 返回Response:send方法返回完全形成的Response对象给你的代码。

模型定义解析

Requests库中的模型定义(高度简化):

class Request:
    """用户创建的Request对象。用于准备PreparedRequest。"""
    def __init__(self, method=None, url=None, headers=None, data=None):
        self.method = method
        self.url = url
        # 其他属性...

    def prepare(self):
        """构造用于传输的PreparedRequest。"""
        p = PreparedRequest()
        p.prepare(method=self.method, url=self.url)
        return p

class PreparedRequest:
    """完全可变的PreparedRequest对象,包含将发送到服务器的确切字节。"""
    def __init__(self):
        self.method = None
        self.url = None
        self.headers = None
        self.body = None

    def prepare(self, method=None, url=None, headers=None, data=None):
        """准备整个请求。"""
        self.method = method
        self.url = url  # 处理后的url
        self.headers = headers  # 最终头
        self.body = data  # 编码后的正文字节或流

class Response:
    """包含服务器对HTTP请求的响应。"""
    def __init__(self):
        self._content = False  # 内容尚未读取
        self.status_code = None
        self.headers = CaseInsensitiveDict()  # 头信息的特殊字典
        self.raw = None  # 来自网络连接的原始流
        self.url = None
        self.encoding = None

    @property
    def content(self):
        """响应的内容,以字节为单位。"""
        return self._content

    @property
    def text(self):
        """响应的内容,以unicode表示。"""
        return decoded_string

    def json(self):
        """返回响应的json编码内容(如果有的话)。"""
        return python_object

总结

通过本文,我们深入理解了Requests库中的核心数据载体:

  • Request:你的初始意图
  • PreparedRequest:准备发送的最终请求
  • Response:服务器的回复,包含状态、头和内容

虽然你主要是在发起请求后与Response对象交互,但了解Request和PreparedRequest有助于理解整个过程。我们探索了Response对象的有用属性,如status_code、headers、text、content和方便的json()方法。

理解这些模型能让你更清楚地看到Requests库如何将简单的函数调用转化为网络操作,并将结果整洁地打包给你使用。

【免费下载链接】Tutorial-Codebase-Knowledge Turns Codebase into Easy Tutorial with AI 【免费下载链接】Tutorial-Codebase-Knowledge 项目地址: https://gitcode.com/gh_mirrors/tu/Tutorial-Codebase-Knowledge

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值