杰瑞科技汇

Python requests如何高效解析响应数据?

目录

  1. 简介与安装
  2. 核心概念:发送你的第一个请求
  3. 核心功能详解
  4. 高级用法
  5. 最佳实践与常见问题
  6. 官方文档

简介

requests 库是一个第三方库,不是 Python 标准库的一部分,它基于 urllib3 构建,提供了更简洁、更高级的 API,让你能用几行代码就完成复杂的 HTTP 交互。

Python requests如何高效解析响应数据?-图1
(图片来源网络,侵删)

安装

在使用之前,你需要先安装它,打开你的终端或命令行工具,运行以下命令:

pip install requests

核心概念:发送你的第一个请求

requests 的核心非常简单:requests.<method>(url, ...)

让我们从一个最简单的 GET 请求开始,目标是获取 httpbin.org 的 IP 地址信息(这是一个专门用于测试 HTTP 请求的网站)。

import requests
# 目标 URL
url = 'https://httpbin.org/ip'
try:
    # 发送 GET 请求
    response = requests.get(url)
    # 打印响应状态码
    print(f"状态码: {response.status_code}")
    # 打印响应内容(文本格式)
    print(f"响应内容: {response.text}")
except requests.exceptions.RequestException as e:
    print(f"请求发生错误: {e}")

输出:

Python requests如何高效解析响应数据?-图2
(图片来源网络,侵删)
状态码: 200 {
  "origin": "123.45.67.89" 
}

这就是 requests 的基本用法:导入库,调用请求方法(如 get),传入 URL,然后处理返回的 response 对象。

核心功能详解

1. 请求方法 (GET, POST, PUT, DELETE 等)

requests 为所有常见的 HTTP 方法都提供了便捷的函数:

  • requests.get(url): 获取资源。
  • requests.post(url): 提交数据,通常用于创建新资源。
  • requests.put(url): 更新资源。
  • requests.delete(url): 删除资源。
  • requests.patch(url): 对资源进行部分修改。
  • requests.head(url): 获取 HTTP 头部信息。
  • requests.options(url): 获取服务器支持的 HTTP 方法。

示例 (POST 请求):

import requests
url = 'https://httpbin.org/post'
data = {
    'key1': 'value1',
    'key2': 'value2'
}
# 发送 POST 请求,并传递表单数据
response = requests.post(url, data=data)
print(f"状态码: {response.status_code}")
print(f"响应的 Form Data: {response.json()['form']}")

2. 传递 URL 参数 (params)

当需要向 URL 的查询字符串( 后面的部分)添加参数时,使用 params 参数。requests 会自动为你进行 URL 编码。

Python requests如何高效解析响应数据?-图3
(图片来源网络,侵删)
import requests
url = 'https://httpbin.org/get'
# 参数可以是一个字典
payload = {'key1': 'value1', 'key2': 'value2'}
# 发送 GET 请求,并传递参数
response = requests.get(url, params=payload)
# 你可以检查最终的请求 URL
print(f"请求的 URL: {response.url}") 
# 输出: 请求的 URL: https://httpbin.org/get?key1=value1&key2=value2
print(f"响应内容: {response.json()['args']}")

3. 请求头 (headers)

通过 headers 参数,你可以自定义请求头,例如修改 User-Agent、设置 Content-Type 等。

import requests
url = 'https://httpbin.org/headers'
headers = {
    'User-Agent': 'MyCoolApp/1.0',
    'Accept': 'application/json'
}
response = requests.get(url, headers=headers)
print(f"响应内容: {response.json()['headers']}")
# 你会看到 'User-Agent' 和 'Accept' 都被成功发送了

4. 请求体 (data, json)

当发送 POST, PUT 等请求时,需要传递请求体。requests 提供了两种主要方式:

  • data: 用于发送表单数据(application/x-www-form-urlencodedmultipart/form-data),如果传入一个字典,requests 会自动编码。

    payload = {'username': 'john', 'password': 'secret'}
    response = requests.post('https://httpbin.org/post', data=payload)
  • json: 用于发送 JSON 编码的数据(application/json)。requests 会自动将 Python 字典/列表序列化为 JSON 字符串,并设置正确的 Content-Type 头。

    import json
    payload = {'username': 'john', 'password': 'secret'}
    # 推荐:使用 json 参数
    response = requests.post('https://httpbin.org/post', json=payload)
    # 等同于下面这种方式,但更简洁
    # response = requests.post('https://httpbin.org/post', data=json.dumps(payload), headers={'Content-Type': 'application/json'})

5. 响应对象 (Response)

当你调用 requests.get() 等方法后,它会返回一个 Response 对象,这个对象包含了服务器对请求的所有响应信息。

常用属性包括:

  • response.status_code: HTTP 状态码 (如 200, 404, 500)。
  • response.headers: 响应头,是一个类字典对象。
  • response.cookies: 服务器返回的 cookies。
  • response.url: 最终请求的 URL(可能会因为重定向而改变)。
  • response.history: 重定向历史(一个包含 Response 对象的列表)。
  • response.elapsed: 请求花费的时间。

6. 处理响应内容 (text, content, json())

Response 对象提供了多种方式来访问响应体:

  • response.text: 将响应体作为字符串返回。requests 会根据 HTTP 头部中的 encoding 来解码,如果编码无法确定,它会尝试使用 chardet 库进行猜测,对于非文本数据(如图片),不推荐使用。
  • response.content: 将响应体作为字节串 (bytes) 返回,这对于处理二进制数据(如图片、PDF、视频)至关重要。
  • response.json(): 如果响应体是 JSON 格式,这个方法会将其解析为 Python 字典或列表,如果响应不是有效的 JSON,它会抛出 JSONDecodeError 异常。

示例:下载图片

import requests
img_url = 'https://httpbin.org/image/png'
response = requests.get(img_url, stream=True) # stream=True 见高级用法
# 检查请求是否成功
if response.status_code == 200:
    # 使用 content 获取二进制数据
    with open('downloaded_image.png', 'wb') as f:
        f.write(response.content)
    print("图片下载成功!")
else:
    print(f"下载失败,状态码: {response.status_code}")

高级用法

1. 会话对象 (Session)

Session 对象允许你在多个请求之间保持某些参数,cookies,当你向同一个主机发送多个请求时,使用 Session 可以提高性能,因为它会重用底层的 TCP 连接(HTTP Keep-Alive)。

import requests
# 1. 创建一个 Session 对象
with requests.Session() as session:
    # 2. 在会话中设置持久参数(如 cookies, headers)
    session.headers.update({'User-Agent': 'MyApp/1.0'})
    # 第一个请求,服务器可能设置了一个 cookie
    response1 = session.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
    print(f"第一次请求的 Cookies: {response1.cookies.get_dict()}")
    # 第二个请求,会自动带上第一个请求设置的 cookie
    response2 = session.get('https://httpbin.org/cookies')
    print(f"第二次请求的响应: {response2.json()}")
    # 你会看到 'sessioncookie': '123456789' 在返回的 cookies 中

2. 身份验证 (auth)

对于需要 Basic Auth 或 Digest Auth 的网站,requests 提供了非常简单的 auth 参数。

from requests.auth import HTTPBasicAuth, HTTPDigestAuth
import requests
# Basic Auth
url = 'https://httpbin.org/basic-auth/user/passwd'
auth = HTTPBasicAuth('user', 'passwd')
response = requests.get(url, auth=auth)
print(f"状态码: {response.status_code}") # 应该是 200
print(f"认证信息: {response.json()}")
# Digest Auth (类似)
# digest_auth = HTTPDigestAuth('user', 'passwd')
# response = requests.get(url, auth=digest_auth)

3. 超时与重试 (timeout, retry)

  • 超时 (timeout): 为了防止程序因网络问题或服务器无响应而无限期挂起,必须设置超时。timeout 可以是一个浮点数(秒),或者一个元组 (连接超时, 读取超时)

    # 10秒后连接超时
    # requests.get('https://httpbin.org/delay/5', timeout=10) 
    # 3秒后连接超时,5秒后读取超时
    # requests.get('https://httpbin.org/delay/5', timeout=(3, 5))
  • 重试: requests 本身不内置重试机制,但可以使用第三方库 requests-toolbelturllib3Retry 功能,更简单的方式是使用 requests.adaptersurllib3.util.Retry 结合。

    import requests
    from requests.adapters import HTTPAdapter
    from urllib3.util.retry import Retry
    def create_session_with_retries(retries=3, backoff_factor=0.3):
        session = requests.Session()
        retry = Retry(
            total=retries,
            read=retries,
            connect=retries,
            backoff_factor=backoff_factor,
            status_forcelist=(500, 502, 504)
        )
        adapter = HTTPAdapter(max_retries=retry)
        session.mount('http://', adapter)
        session.mount('https://', adapter)
        return session
    session = create_session_with_retries()
    try:
        response = session.get('https://httpbin.org/status/500')
        print(f"最终状态码: {response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"所有重试均失败: {e}")

4. SSL 证书验证 (verify)

默认情况下,requests 会验证 SSL 证书,如果目标网站使用的是自签名证书,或者你处于一个抓包调试环境(如 Charles, Fiddler),你需要禁用证书验证。

警告: 禁用 verify 会使你的连接不安全,容易受到中间人攻击。仅应在受信任的开发环境中使用。

# 禁用 SSL 证书验证
# response = requests.get('https://self-signed.badssl.com/', verify=False)
# 会看到 InsecureRequestWarning 警告

5. 代理 (proxies)

当你需要通过 HTTP/HTTPS/SOCKS 代理发送请求时,可以使用 proxies 参数。

proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'http://10.10.1.10:1080',
}
# response = requests.get('https://httpbin.org/ip', proxies=proxies)

6. 流式下载 (stream)

对于大文件(如视频、大日志文件),直接使用 response.content 会将整个文件加载到内存中,可能导致内存不足,使用 stream=True 可以分块下载,将文件流式地写入磁盘。

import requests
url = 'https://httpbin.org/stream/10' # 一个返回10行文本的流式接口
with requests.get(url, stream=True) as r:
    r.raise_for_status() # 如果请求失败,抛出 HTTPError 异常
    for line in r.iter_lines():
        # line 是 bytes 类型,需要解码
        if line: # 过滤掉空行
            print(line.decode('utf-8'))

最佳实践与常见问题

1. 使用 try...except 处理异常

网络是不可靠的,你的代码必须能够处理各种异常。

import requests
from requests.exceptions import RequestException
url = 'https://api.github.com' # 一个可能不稳定的 URL
try:
    response = requests.get(url, timeout=5)
    # 如果状态码不是 2xx,则抛出 HTTPError 异常
    response.raise_for_status() 
    print(response.json())
except RequestException as e:
    # RequestException 是 requests 所有异常的基类
    print(f"请求失败: {e}")
except requests.exceptions.HTTPError as e:
    # raise_for_status() 抛出的具体异常
    print(f"HTTP 错误: {e}")
except requests.exceptions.ConnectionError as e:
    print(f"连接错误: {e}")
except requests.exceptions.Timeout as e:
    print(f"请求超时: {e}")

2. 指定 User-Agent

很多网站会检查 User-Agent 来判断请求是否来自浏览器,为了避免被屏蔽,最好设置一个常见的浏览器 User-Agent

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)

3. 设置合理的超时时间

永远不要发送不带超时时间的请求! 这是一个黄金法则,至少设置一个连接超时(如 5-10 秒)。

4. 使用会话 (Session) 提升性能

如果你在短时间内向同一个域名发送多个请求,请使用 Session 对象,它可以复用 TCP 连接,显著提高性能。

requests 库是 Python 程序员进行网络请求的必备工具,它的设计哲学是“简单易用”。

  • 入门简单requests.get() 是你唯一需要记住的核心。
  • 功能强大:从参数、请求头、认证到代理、流式下载,它几乎涵盖了所有 HTTP 场景。
  • 人性化:自动处理编码、JSON 解析、会话管理等繁琐细节。

掌握了上述核心和高级用法,你就可以应对绝大多数 Python 网络编程任务了。

官方文档

requests 的官方文档写得非常出色,是学习和查阅的最佳资源。

Requests Official Documentation (v2.31.0)

分享:
扫描分享到社交APP
上一篇
下一篇