实战目标
我们将以一个模拟的 API 为例,完成以下任务:

- GET 请求:获取数据列表。
- POST 请求:创建新数据。
- PUT 请求:更新现有数据。
- DELETE 请求:删除数据。
- 身份验证:使用 API Key 进行认证。
- 处理 JSON 响应:解析和构造 JSON 数据。
- 异常处理:优雅地处理网络错误和 API 错误。
- 使用 Session:保持连接,提高效率。
准备工作:安装 Requests 库
如果你的 Python 环境还没有安装 requests 库,请先打开终端或命令行,运行以下命令:
pip install requests
实战步骤
第 1 步:发送一个简单的 GET 请求
我们的模拟 API 是一个在线的 JSONPlaceholder 服务,它非常适合用于测试和学习。
目标:获取所有用户的列表。
import requests
import json # 用于美化打印 JSON
# API 端点
url = "https://jsonplaceholder.typicode.com/users"
try:
# 发送 GET 请求
response = requests.get(url)
# 检查请求是否成功 (状态码 200-299)
response.raise_for_status()
# 获取响应内容,并解析为 JSON 对象
users = response.json()
# 打印第一个用户的信息
print("成功获取用户列表!")
print("第一个用户信息:")
print(json.dumps(users[0], indent=4, ensure_ascii=False))
except requests.exceptions.HTTPError as http_err:
print(f"HTTP 错误发生: {http_err}")
except requests.exceptions.ConnectionError as conn_err:
print(f"连接错误发生: {conn_err}")
except requests.exceptions.Timeout as timeout_err:
print(f"请求超时: {timeout_err}")
except requests.exceptions.RequestException as err:
print(f"发生未知错误: {err}")
代码解析:

requests.get(url): 发送 GET 请求。response.raise_for_status(): 这是一个非常好的习惯,如果响应的状态码表示错误(404 Not Found, 500 Server Error),它会抛出一个HTTPError异常。response.json(): 将响应内容(必须是有效的 JSON 格式)解析为 Python 的字典或列表。try...except: 捕获可能发生的网络请求异常,使程序更健壮。
第 2 步:发送 POST 请求创建新数据
目标:创建一个新的“待办事项”(Todo)。
import requests
import json
# API 端点
url = "https://jsonplaceholder.typicode.com/todos"
# 要创建的数据(字典格式)
payload = {
"userId": 1,: "学习 Python Requests",
"completed": False
}
# 发送 POST 请求
# data 参数用于发送表单数据,json 参数会自动将字典序列化为 JSON 字符串,
# 并设置正确的 Content-Type 头。
response = requests.post(url, json=payload)
# 检查响应
response.raise_for_status()
# 获取新创建的数据
new_todo = response.json()
print("\n成功创建新的待办事项!")
print(json.dumps(new_todo, indent=4, ensure_ascii=False))
代码解析:
requests.post(url, json=payload): 发送 POST 请求。json=payload: 这是requests库的强大功能之一,它会自动将 Python 字典payload序列化为 JSON 字符串,并设置Content-Type: application/json请求头,你也可以使用data=payload来发送表单数据(Content-Type: application/x-www-form-urlencoded)。- 服务器通常会返回刚刚创建的对象,包括它的新 ID。
第 3 步:发送 PUT 请求更新数据
目标:将 ID 为 1 的待办事项标记为已完成。
import requests
import json
# API 端点,包含要更新的资源的 ID
url = "https://jsonplaceholder.typicode.com/todos/1"
# 更新后的数据
updated_payload = {
"userId": 1,: "学习 Python Requests (已完成)",
"completed": True
}
# 发送 PUT 请求
response = requests.put(url, json=updated_payload)
response.raise_for_status()
updated_todo = response.json()
print("\n成功更新待办事项!")
print(json.dumps(updated_todo, indent=4, ensure_ascii=False))
代码解析:

requests.put(url, json=payload): 发送 PUT 请求,用于更新资源,URL 中包含了资源的 ID (/todos/1)。- PUT 请求通常是幂等的,意味着多次执行同一 PUT 请求,结果都是一样的。
第 4 步:发送 DELETE 请求删除数据
目标:删除 ID 为 1 的待办事项。
import requests
url = "https://jsonplaceholder.typicode.com/todos/1"
# 发送 DELETE 请求
response = requests.delete(url)
response.raise_for_status()
# 对于 DELETE 请求,响应体通常是空的或者只包含一个状态码
print(f"\n成功删除待办事项!状态码: {response.status_code}")
代码解析:
requests.delete(url): 发送 DELETE 请求。- 删除成功后,服务器通常会返回一个
200 OK或204 No Content状态码,响应体为空。
第 5 步:添加查询参数
目标:获取所有 ID 为 1 的用户的帖子。
很多 API 允许通过 URL 的查询参数来过滤数据,我们可以使用 params 参数来实现。
import requests
import json
# API 基础 URL
base_url = "https://jsonplaceholder.typicode.com/posts"
# 查询参数字典
query_params = {
"userId": 1
}
# 发送 GET 请求,并传入查询参数
response = requests.get(base_url, params=query_params)
response.raise_for_status()
posts = response.json()
print(f"\n成功获取用户 1 的所有帖子,共 {len(posts)} 条:")
for post in posts:
print(f"- ID: {post['id']}, 标题: {post['title']}")
代码解析:
requests.get(url, params=query_params):params参数是一个字典,requests会自动将其编码并附加到 URL 后,https://jsonplaceholder.typicode.com/posts?userId=1。
第 6 步:处理身份验证
许多受保护的 API 需要身份验证,我们以使用 API Key 为例。
目标:访问一个需要 API Key 的端点。
(注意:JSONPlaceholder 不需要 API Key,这里我们模拟一个场景)
import requests
# 模拟一个需要 API Key 的端点
url = "https://api.example.com/v1/protected_data"
# 你的 API Key (实际项目中应从安全的地方读取,如环境变量)
api_key = "YOUR_SECRET_API_KEY"
# 设置请求头
headers = {
"Authorization": f"Bearer {api_key}", # 常见的 Bearer Token 认证方式
"Content-Type": "application/json"
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
print("\n成功获取受保护的数据!")
print(data)
except requests.exceptions.HTTPError as http_err:
# API 返回 401 Unauthorized 或 403 Forbidden
if response.status_code == 401:
print("错误:API Key 无效或已过期!")
else:
print(f"HTTP 错误发生: {http_err}")
except requests.exceptions.RequestException as err:
print(f"发生未知错误: {err}")
代码解析:
headers: 我们创建一个字典来存放请求头。Authorization: 这是常见的认证头字段。Bearer是一种令牌类型,后面跟着你的密钥或令牌。- 最佳实践:不要将 API Key 硬编码在代码中,应该使用环境变量或配置文件来管理敏感信息。
第 7 步:使用 Session 对象
当你需要对同一个服务器进行多次请求时,使用 Session 对象会非常高效。Session 对象会保持 TCP 连接,避免了重复建立和断开连接的开销,并且可以跨请求保持某些参数(如 cookies)。
目标:使用 Session 对象获取用户信息,然后创建该用户的帖子。
import requests
import json
# 创建一个 Session 对象
with requests.Session() as session:
# 可以设置一些会话级别的参数,headers
session.headers.update({'User-Agent': 'MyPythonApp/1.0'})
# 1. 获取用户 1 的信息
user_url = "https://jsonplaceholder.typicode.com/users/1"
user_response = session.get(user_url)
user_response.raise_for_status()
user = user_response.json()
print(f"\n会话模式: 获取用户 '{user['name']}' 的信息")
# 2. 为该用户创建一个帖子
posts_url = "https://jsonplaceholder.typicode.com/posts"
new_post = {
"title": "我的第一篇来自会话的帖子",
"body": "这是使用 requests.Session 创建的。",
"userId": user['id']
}
post_response = session.post(posts_url, json=new_post)
post_response.raise_for_status()
created_post = post_response.json()
print("成功创建帖子!")
print(json.dumps(created_post, indent=4, ensure_ascii=False))
# 'with' 语句块结束后,会话会自动关闭
代码解析:
requests.Session(): 创建一个会话对象。with ... as session: 使用with语句可以确保会话在使用完毕后被正确关闭,释放资源。session.headers.update(...): 为整个会话设置默认的请求头。- 后续的
session.get()和session.post()都会复用这个会话的连接和设置。
总结与进阶
通过以上实战,你已经掌握了 requests 库的核心用法:
| 功能 | 方法/参数 | 关键点 |
|---|---|---|
| HTTP 方法 | requests.get(), post(), put(), delete() |
对应 HTTP 动词 |
| 数据传递 | json= (JSON), data= (表单) |
根据API要求选择 |
| URL 参数 | params= (字典) |
自动编码并附加到URL |
| 请求头 | headers= (字典) |
用于认证、内容类型等 |
| 身份验证 | headers['Authorization'] |
Bearer Token, API Key 等 |
| 响应处理 | response.json(), response.text, response.status_code |
解析数据,检查状态 |
| 异常处理 | try...except requests.exceptions... |
raise_for_status() 是好习惯 |
| 高效请求 | requests.Session() |
保持连接,适合批量请求 |
进阶方向:
- 异步请求:如果你需要同时发起大量请求,可以使用
aiohttp库进行异步 I/O,性能更高。 - 更复杂的认证:学习 OAuth2.0 认证流程,
requests-oauthlib库可以帮助你处理。 - 上传文件:使用
files参数来上传文件。 - 代理:通过
proxies参数配置代理服务器。 - 超时设置:为请求设置超时时间,防止程序无限等待 (
timeout=10)。
requests 是 Python 爬虫和 API 交互的瑞士军刀,熟练掌握它将为你的开发工作带来巨大便利。
