RESTful API 是目前最流行的 Web 服务架构,Python 提供了多种库来与 RESTful API 交互,其中最常用、最推荐的是 requests 库。

下面我将从以下几个方面进行说明:
- 核心概念:快速回顾 RESTful API 的基本要素。
- 环境准备:安装
requests库。 - 基本操作:使用
requests进行 GET, POST, PUT, DELETE 等操作。 - 进阶技巧:处理认证、会话、上传文件、处理 JSON/XML 数据等。
- 实战案例:以一个公共 API(如 JSONPlaceholder)为例,进行完整的调用。
- 其他库简介:介绍
httpx和aiohttp等替代方案。
核心概念回顾
在开始编码前,简单回顾一下 RESTful API 的几个关键点:
- URL (端点): API 的访问地址,
https://api.example.com/v1/users。 - HTTP 方法: 表示对资源的操作。
GET: 获取资源。POST: 创建新资源。PUT: 更新整个资源。PATCH: 部分更新资源。DELETE: 删除资源。
- 请求头: 包含附加信息,如
Content-Type(内容类型),Authorization(认证信息) 等。 - 请求体: 发送给服务器的数据,通常是 JSON 格式。
- 响应: 服务器返回的数据,包含状态码 (如 200, 404, 500) 和响应体。
环境准备
requests 库不是 Python 的标准库,需要单独安装。
打开你的终端或命令行工具,运行以下命令:

pip install requests
基本操作 (requests 库)
requests 库的设计非常直观,其方法名直接对应 HTTP 方法。
1 GET 请求 - 获取数据
GET 请求用于从服务器获取数据,通常不需要请求体。
import requests
import json # 用于美化打印 JSON
# API 端点 (使用一个免费的公共测试 API)
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
# 发送 GET 请求
response = requests.get(url)
# 检查请求是否成功 (状态码为 2xx)
response.raise_for_status() # 如果状态码不是 2xx,则抛出异常
# 获取响应内容 (通常是 JSON 字符串)
# response.text 是原始字符串
# response.json() 会自动将 JSON 字符串解析为 Python 字典
data = response.json()
print("请求成功!")
print(f"状态码: {response.status_code}")
print("响应数据:")
print(json.dumps(data, indent=4, ensure_ascii=False))
except requests.exceptions.HTTPError as errh:
print(f"HTTP 错误: {errh}")
except requests.exceptions.ConnectionError as errc:
print(f"连接错误: {errc}")
except requests.exceptions.Timeout as errt:
print(f"请求超时: {errt}")
except requests.exceptions.RequestException as err:
print(f"发生错误: {err}")
2 POST 请求 - 创建数据
POST 请求用于向服务器提交数据,通常需要将数据放在请求体中。
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts"
# 要创建的数据 (Python 字典)
payload = {: 'foo',
'body': 'bar',
'userId': 1
}
# 将字典转换为 JSON 字符串,并设置请求头
headers = {
'Content-Type': 'application/json; charset=UTF-8'
}
try:
# 发送 POST 请求,data 参数用于发送 JSON 数据
response = requests.post(url, data=json.dumps(payload), headers=headers)
response.raise_for_status()
# 获取服务器返回的新创建的数据
created_data = response.json()
print("POST 请求成功!")
print(f"状态码: {response.status_code}")
print("服务器返回的数据:")
print(json.dumps(created_data, indent=4, ensure_ascii=False))
except requests.exceptions.RequestException as err:
print(f"发生错误: {err}")
注意: requests.post() 的 data 参数期望接收一个字典,它会自动将其编码为 application/x-www-form-urlencoded 格式,如果要发送 application/json 格式的数据,有两种推荐方式:

data=json.dumps(payload), headers={'Content-Type': 'application/json'}(如上所示)json=payload(更简单,requests会自动帮你处理编码和设置头)
上面的代码可以简化为:
# 更简洁的 POST 方式 response = requests.post(url, json=payload)
3 PUT / PATCH 请求 - 更新数据
PUT 用于替换整个资源,PATCH 用于部分更新,用法与 POST 类似。
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts/1"
# 更新后的数据
# PUT 要求提供完整的资源,包括未修改的字段
put_payload = {
'id': 1,: 'updated title with PUT',
'body': 'updated body with PUT',
'userId': 1
}
# PATCH 只需要提供需要修改的字段
patch_payload = {: 'updated title with PATCH'
}
headers = {'Content-Type': 'application/json'}
# 发送 PUT 请求
response_put = requests.put(url, json=put_payload, headers=headers)
print(f"PUT 状态码: {response_put.status_code}")
print("PUT 响应:", response_put.json())
# 发送 PATCH 请求
response_patch = requests.patch(url, json=patch_payload, headers=headers)
print(f"\nPATCH 状态码: {response_patch.status_code}")
print("PATCH 响应:", response_patch.json())
4 DELETE 请求 - 删除数据
DELETE 请求通常不需要请求体。
import requests
url = "https://jsonplaceholder.typicode.com/posts/1"
try:
response = requests.delete(url)
response.raise_for_status()
print(f"DELETE 请求成功!状态码: {response.status_code}")
# 删除操作通常返回一个空响应体或确认信息
print("响应内容:", response.text)
except requests.exceptions.RequestException as err:
print(f"发生错误: {err}")
进阶技巧
1 传递 URL 参数
当需要通过 URL 传递查询参数时(如 ?key1=value1&key2=value2),可以使用 params 参数。
import requests
url = "https://jsonplaceholder.typicode.com/posts"
# params 是一个字典
query_params = {
'userId': 1,
'_limit': 5 # 获取前5条
}
response = requests.get(url, params=query_params)
print(f"请求URL: {response.url}") # 可以看到URL已经被正确构建
print("查询结果:")
print(response.json())
2 处理认证
许多 API 需要认证。requests 支持多种认证方式,最常见的是 API Key 或 Bearer Token。
在请求头中添加 API Key
import requests
url = "https://api.example.com/data"
api_key = "YOUR_API_KEY_HERE"
headers = {
'Authorization': f'Bearer {api_key}', # 或者 'X-API-KEY': api_key
'Content-Type': 'application/json'
}
response = requests.get(url, headers=headers)
print(response.json())
使用 requests.auth 模块 (适用于 Basic Auth)
import requests from requests.auth import HTTPBasicAuth url = "https://api.example.com/protected" username = 'user' password = 'pass' # 使用 HTTPBasicAuth response = requests.get(url, auth=HTTPBasicAuth(username, password)) print(response.json())
3 使用会话
如果你需要向同一个主机发送多个请求,使用 Session 对象可以更高效,它会保持一个连接池,并自动处理 cookies。
import requests
# 创建一个 Session 对象
with requests.Session() as session:
# 为该会话设置通用头信息
session.headers.update({'User-Agent': 'MyApp/1.0'})
# 第一次请求,可能会设置 cookies
response1 = session.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
print("第一次请求:", response1.json())
# 第二次请求,会自动带上第一次设置的 cookies
response2 = session.get('https://httpbin.org/cookies')
print("第二次请求 (会带上 cookies):", response2.json())
4 上传文件
使用 files 参数来上传文件。
import requests
url = "https://httpbin.org/post"
# 打开文件,准备上传
with open('my_file.txt', 'rb') as f:
files = {'file': f}
response = requests.post(url, files=files)
print("文件上传响应:")
print(response.json())
实战案例:与 JSONPlaceholder API 交互
这个 API 是一个免费的在线 REST API,非常适合测试和学习。
目标:获取所有用户,然后为第一个用户创建一篇新文章。
import requests
import json
# API 基础 URL
BASE_URL = "https://jsonplaceholder.typicode.com"
def get_users():
"""获取所有用户"""
print("--- 正在获取所有用户 ---")
response = requests.get(f"{BASE_URL}/users")
response.raise_for_status()
users = response.json()
print(f"成功获取 {len(users)} 个用户。")
# 返回第一个用户的 ID
return users[0]['id']
def create_post_for_user(user_id, title, body):
"""为指定用户创建一篇新文章"""
print(f"\n--- 正在为用户 ID {user_id} 创建新文章 ---")
payload = {
'title': title,
'body': body,
'userId': user_id
}
response = requests.post(f"{BASE_URL}/posts", json=payload)
response.raise_for_status()
new_post = response.json()
print("文章创建成功!")
return new_post
if __name__ == "__main__":
try:
# 1. 获取用户
first_user_id = get_users()
# 2. 为该用户创建文章
new_article = create_post_for_user(
user_id=first_user_id,
title="我的第一篇 Python API 文章",
body="这是通过 Python requests 库创建的,感觉真棒!"
)
# 3. 打印结果
print("\n--- 最终结果 ---")
print(json.dumps(new_article, indent=4, ensure_ascii=False))
except requests.exceptions.RequestException as e:
print(f"API 调用过程中发生错误: {e}")
其他库简介
除了 requests,还有其他优秀的库适用于不同场景。
httpx
httpx 是一个现代化的 HTTP 客户端,支持同步和异步请求,并且支持 HTTP/2,如果你正在使用 asyncio,httpx 是比 requests 更好的选择。
# httpx 同步用法 (与 requests 几乎一样)
import httpx
with httpx.Client() as client:
response = client.get("https://httpbin.org/get")
print(response.json())
# httpx 异步用法 (需要 Python 3.7+)
import asyncio
import httpx
async def main():
async with httpx.AsyncClient() as client:
response = await client.get("https://httpbin.org/get")
print(response.json())
asyncio.run(main())
aiohttp
aiohttp 是另一个非常流行的异步 HTTP 客户端/服务器库,它与 asyncio 紧密集成,是异步网络请求的“老牌”选择。
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.json()
async def main():
url = "https://httpbin.org/get"
async with aiohttp.ClientSession() as session:
data = await fetch(session, url)
print(data)
asyncio.run(main())
| 库 | 特点 | 适用场景 |
|---|---|---|
requests |
简单、易用、同步、功能全面 | 绝大多数场景的首选,特别是快速脚本、常规 Web 爬虫、与第三方 API 集成。 |
httpx |
现代化,支持同步/异步,支持 HTTP/2 | 新项目,特别是已经或计划使用 asyncio 的项目。 |
aiohttp |
纯异步,高性能 | 高性能异步应用,如异步爬虫、异步微服务。 |
对于初学者和绝大多数日常开发任务,requests 是你的不二之选,掌握它,你就能轻松应对绝大多数 RESTful API 的调用需求。
