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

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

1. 简介

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

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

2. 安装

一条命令就能搞定(支持 Python 3.7+ 版本):

pip install requests

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

Requests 支持所有标准 HTTP 方法,我们先从最常用的 GETPOST 开始。

发送 GET 请求

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

import requests

# 发送请求
response = requests.get('https://httpbin.org/get')

# 打印响应文本(自动处理编码)
print(response.text)

发送 POST 请求

提交表单或简单数据用 data 参数:

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

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

# 直接解析 JSON 响应(httpbin 会返回请求详情)
print(response.json())

其他标准 HTTP 方法

Requests 也支持 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')  # 检查目标支持的 HTTP 方法

4. 请求参数:自定义你的请求

上面的例子太基础了,实际开发中我们经常需要传 URL 参数、自定义请求头、发 JSON 数据。

传递 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

自定义请求头

比如模拟浏览器访问、添加 API Token,用 headers 参数:

custom_headers = {
    'User-Agent': 'My-Python-App/1.0.0',  # 自定义 User-Agent
    '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 了:

import requests  # 不需要额外导入 json 库哦!

json_data = {'title': 'Python Requests', 'content': 'This is a tutorial'}

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

5. 响应处理:快速获取需要的信息

Requests 返回的 Response 对象封装得非常完善,下面是几个最常用的属性和方法。

获取响应内容

根据响应类型选择合适的属性:

  • response.text:自动解码的文本内容
  • response.content二进制内容(适合图片、视频等非文本文件)
  • response.json():直接解析成Python 字典/列表(如果响应不是合法 JSON,会抛出异常)
response = requests.get('https://httpbin.org/get')

# 文本
print("=== 响应文本 ===")
print(response.text[:100])  # 只打印前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'])

检查状态码

  • response.status_code:直接获取数字状态码
  • response.raise_for_status():自动检查状态码,如果不是 2xx 会抛出异常
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

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

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

# 第一次请求:模拟登录(这里 httpbin 会返回设置的 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()

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 把常见的错误都封装成了异常类,用 try-except 捕获即可:

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:处理多请求场景,提高性能
  3. 用 response.raise_for_status():自动检查 HTTP 状态码
  4. 使用流式处理大文件:避免一次性加载整个文件到内存(见下节性能优化)
  5. 捕获特定异常:不要只捕获 RequestException,方便调试和处理不同情况
  6. 遵循目标网站的 robots.txt:不要恶意爬取
  7. 使用环境变量存储敏感信息:比如 API Token、密码,不要直接写在代码里

9. 总结

Requests 是 Python 生态中最值得推荐的 HTTP 客户端库,它用极简的 API 解决了 urllib 的所有痛点,无论是简单的接口调用还是复杂的爬虫开发都能轻松应对。

如果你想深入了解 Requests,可以查看官方文档,里面还有更多高级功能比如文件上传、流式请求、代理设置、OAuth 认证等。