Python Requests 库使用教程:告别 urllib 的繁琐

你是不是还在为 Python 内置 urllib 的复杂编码拼接、证书配置、多会话管理头疼?今天我们就来聊一聊 Python 生态中最受欢迎的 HTTP 客户端库——Requests,它用极简的 API 封装了几乎所有日常开发需要的 HTTP 功能,上手门槛极低,效率却很高。

1. 简介

Requests 的官方口号是「HTTP for Humans(为人类设计的 HTTP 库)」,这句话一点也不夸张:

  • 内置了自动编码解码、JSON 解析、状态码检查等常用功能
  • 支持连接保持池、Cookie 持久化、文件分块上传/下载
  • 处理异常、设置超时、代理、认证都只需一行参数

无论你是调用外部 API、编写爬虫,还是做接口测试,Requests 都能让你事半功倍。


2. 安装

一条命令就能搞定(支持 Python 3.7+ 版本)。建议在虚拟环境中安装,保持项目依赖干净:

pip install requests

安装完成后,在代码中直接导入即可使用:

import requests

3. 基本用法:一分钟上手

Requests 支持所有标准 HTTP 方法,我们先从最常用的 GETPOST 开始,然后再快速看一下其它方法。

发送 GET 请求

调用 requests.get() 并传入目标 URL,返回的 Response 对象就包含了所有响应信息:

import requests

# 发送一个简单的 GET 请求
response = requests.get('https://httpbin.org/get')

# 打印响应文本(自动处理编码,无需手动 decode)
print(response.text)

发送 POST 请求

提交表单或简单数据时,直接使用 data 参数,Requests 会自动设置 Content-Type

# 准备要提交的表单数据
form_data = {'username': 'python_user', 'email': 'user@example.com'}

# 发送 POST 请求
response = requests.post('https://httpbin.org/post', data=form_data)

# 直接解析 JSON 响应(httpbin 会原样返回你发送的请求详情)
print(response.json())

其他标准 HTTP 方法

PUTDELETEHEADOPTIONS 等方法同样简单,用法与 GET / POST 保持一致:

requests.put('https://httpbin.org/put', data={'key': 'update_value'})
requests.delete('https://httpbin.org/delete')
requests.head('https://httpbin.org/get')        # 只获取响应头
requests.options('https://httpbin.org/get')     # 查看服务器支持的方法

4. 请求参数:随心定制你的请求

真实项目中,我们经常需要拼接 URL 参数、自定义请求头或者发送 JSON 数据,Requests 用几个关键字参数就让这些操作变得异常清爽。

传递 URL 参数

将参数放入字典并传给 params,Requests 会自动完成 URL 编码和拼接:

query_params = {'page': 1, 'limit': 20, 'sort': 'newest'}

response = requests.get('https://httpbin.org/get', params=query_params)

# 查看拼接后的完整 URL
print(response.url)  # 输出:https://httpbin.org/get?page=1&limit=20&sort=newest

💡 小贴士:如果参数值为空或 None,Requests 会忽略该参数,不会在 URL 中带着。

自定义请求头

模拟浏览器访问、添加 API Token、设置 Accept 类型等场景,只需传入一个字典给 headers 参数:

custom_headers = {
    'User-Agent': 'My-Python-App/1.0.0',          # 自定义客户端标识
    'Authorization': 'Bearer YOUR_API_TOKEN',     # 常见的 Bearer Token 认证
}

response = requests.get('https://api.example.com/data', headers=custom_headers)

发送 JSON 数据

越来越多的 API 要求使用 JSON 格式的请求体,Requests 专门提供了 json 参数,无需手动 json.dumps() 和设置 Content-Type

# 注意:不需要额外导入 json 库
json_data = {
    'title': 'Python Requests',
    'content': 'This is a tutorial'
}

response = requests.post('https://httpbin.org/post', json=json_data)

5. 响应处理:快速提取有用信息

Response 对象封装得非常完善,根据不同需要,你可以选择最合适的属性来获取响应内容。

获取响应内容

场景使用属性 / 方法说明
普通文本(HTML、JSON 等)response.text自动推测编码并解码成字符串
图片、视频、压缩包等二进制文件response.content返回原始字节数据
JSON 数据response.json()直接解析成 Python 字典或列表

示例:

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

# 文本
print("=== 响应文本(前100字符) ===")
print(response.text[:100])

# 二进制(例如保存一张图片)
img_response = requests.get('https://httpbin.org/image/png')
with open('test.png', 'wb') as f:
    f.write(img_response.content)

# JSON
print("\n=== JSON 响应中的 origin ===")
print(response.json()['origin'])

⚠️ 如果响应不是合法的 JSON,response.json() 会抛出 json.JSONDecodeError,建议放在 try-except 块中使用。

检查状态码

  • response.status_code:直接获取数字状态码
  • response.raise_for_status():自动判断状态码,非 2xx 时抛出 HTTPError 异常
response = requests.get('https://httpbin.org/status/404')  # 模拟 404 错误

print(f"状态码:{response.status_code}")

# 结合 try-except 让错误处理更安全
try:
    response.raise_for_status()
except requests.exceptions.HTTPError as e:
    print(f"HTTP 错误:{e}")

获取响应头

response.headers 是一个类似字典的对象,并且键不区分大小写,用起来非常方便:

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

print("Content-Type:", response.headers['content-type'])
print("Server:", response.headers.get('Server'))   # 推荐使用 get 方法避免 KeyError

6. 高级功能:轻松应对复杂场景

当需要向同一个网站发送多个请求时,Session 对象能复用 TCP 连接,显著提升性能;同时它还会自动管理和携带 Cookie,省去手动处理 Cookie 的麻烦:

# 创建一个会话
session = requests.Session()

# 设置会话级别的请求头(该会话内所有请求都会自动携带)
session.headers.update({'User-Agent': 'My-Session-App/1.0'})

# 第一次请求:模拟设置 Cookie
login_response = session.post('https://httpbin.org/cookies/set', params={'session_id': '123456'})
print("第一次请求后设置的 Cookie:", login_response.json())

# 第二次请求:自动携带上次的 Cookie
data_response = session.get('https://httpbin.org/cookies')
print("第二次请求时服务器收到的 Cookie:", data_response.json())

# 使用完毕后记得关闭会话
session.close()

✅ 你也可以使用 with requests.Session() as session: 语法,避免忘记关闭。

SSL 验证

默认情况下 Requests 会验证 SSL 证书,保证连接安全。如果遇到自签名证书或开发环境,也可以灵活控制验证行为:

# 临时禁用 SSL 验证(仅用于测试,会抛出一个安全警告)
requests.get('https://self-signed.badssl.com', verify=False)

# 生产环境中可以指定自己的 CA 证书
requests.get('https://internal-api.example.com', verify='/path/to/your/ca-cert.pem')

超时设置

务必设置超时! 否则程序可能因网络波动而无限等待。Requests 支持两种超时方式:

  • 元组 (connect_timeout, read_timeout):分别设置连接超时和读取超时
  • 单个数字:总超时时间(连接 + 读取)
# 连接超时 3 秒,读取超时 27 秒
requests.get('https://httpbin.org/delay/5', timeout=(3, 27))

# 总超时 5 秒
try:
    requests.get('https://httpbin.org/delay/10', timeout=5)
except requests.exceptions.Timeout as e:
    print("请求超时:", e)

7. 错误处理:优雅应对各种意外

Requests 把常见的网络和 HTTP 错误都封装成了异常类,使用一个清晰的异常树结构。强烈建议捕获具体的异常类型,而不是仅仅捕获所有异常的父类:

from requests.exceptions import (
    RequestException,   # 所有 Requests 异常的父类,可做兜底
    HTTPError,
    Timeout,
    ConnectionError,
)

try:
    response = requests.get('https://httpbin.org/status/500', timeout=5)
    response.raise_for_status()   # 先检查 HTTP 状态码
except HTTPError as e:
    print(f"HTTP 错误(状态码 >=400):{e}")
except Timeout as e:
    print(f"请求超时:{e}")
except ConnectionError as e:
    print(f"连接错误(如网络不通、DNS 解析失败):{e}")
except RequestException as e:
    print(f"其他 Requests 错误:{e}")

这样你的程序就不会因为一次网络抖动而轻易崩溃。


8. 最佳实践:写出健壮又优雅的代码

  1. 必须设置超时 —— 防止程序无限挂起,尤其是在生产环境
  2. 优先使用 Session —— 多请求场景下可以提高性能并自动管理 Cookie
  3. 养成使用 raise_for_status() 的习惯 —— 自动检测 4xx/5xx,配合exception-handling使用
  4. 处理大文件时开启流式下载 —— 避免一次性将整个文件加载入内存(stream=True
  5. 捕获具体异常 —— 不要只用 RequestException 一锅端,便于调试和针对性处理
  6. 遵守网站的 robots.txt —— 爬虫开发务必保持友好
  7. 敏感信息存环境变量 —— API Token、密码等切勿硬编码,使用 os.getenv().env 文件管理

9. 总结

Requests 是 Python 生态中最值得推荐的 HTTP 客户端库,它用直觉化的 API 解决了 urllib 的所有痛点。无论是简单的接口调用,还是复杂的爬虫、微服务间通信,Requests 都能让你用最少的代码完成最多的工作。

如果你还想探索更多高级功能(文件上传、流式请求、代理设置、OAuth 认证等),请访问 Requests 官方文档,那里有丰富的示例和详尽的说明。现在,就用 pip install requests 开启你的高效 HTTP 之旅吧!