57·模块十二:网络编程进阶

RESTful API 使用与数据解析

apirestjson

第 57 课:RESTful API 使用与数据解析

学习目标

完成本课学习后,你将能够:

  1. 理解 RESTful API 的基本概念和 HTTP 方法的含义。
  2. 使用 requests 库向 API 发送 GET 和 POST 请求。
  3. 成功解析 API 返回的 JSON 格式数据。
  4. 掌握在请求中设置参数、请求头以及处理 API 响应状态码。
  5. 初步具备使用 Python 与网络服务进行数据交互的能力。

核心概念

1. RESTful API 是什么?

简单来说,API (Application Programming Interface) 是程序之间交流的"菜单"。而 RESTful API 是一种设计风格,它利用 HTTP 协议来实现客户端(比如我们的 Python 脚本)与服务器(提供数据或服务的网站)之间的通信。 你可以把它想象成去一家"数据餐厅"点餐:

  • 资源 (Resource):菜单上的每道菜,对应 API 中的一个 URL(端点)。例如,/users 表示所有用户信息。
  • 方法 (Method):你点菜的方式。
    • GET获取信息。相当于"我想看看菜单上有什么菜"。
    • POST提交/创建信息。相当于"我想新增一道菜"。
    • PUT/PATCH更新信息。相当于"我想修改这道菜的做法"。
    • DELETE删除信息。相当于"我想把这道菜从菜单上移除"。

2. JSON 数据格式

API 返回的数据大多是 JSON (JavaScript Object Notation) 格式。它非常像 Python 的字典和列表,非常易读。

{
  "name": "Alice",
  "age": 30,
  "hobbies": ["coding", "reading", "hiking"]
}

对应的 Python 数据结构就是一个字典,其值可以是字符串、数字、列表,甚至另一个字典。

3. 状态码

服务器在响应请求时,会附带一个 HTTP 状态码,告诉我们请求是否成功。

  • 2xx (成功):如 200 OK201 Created
  • 4xx (客户端错误):如 400 Bad Request (请求有误),404 Not Found (资源不存在),401 Unauthorized (未授权)。
  • 5xx (服务器错误):如 500 Internal Server Error (服务器内部错误)。

我们的代码应该根据状态码做出不同的处理。

代码示例

以下示例使用一个公开的测试 API jsonplaceholder 来演示如何进行 GET 和 POST 请求。

import requests
import json

# 1. 发送 GET 请求:获取用户列表
print("--- GET 请求示例 ---")
api_url = "https://jsonplaceholder.typicode.com/users"
response = requests.get(api_url)

# 检查请求是否成功 (状态码为 2xx)
if response.status_code == 200:
    # 将响应的 JSON 内容解析为 Python 对象
    users_data = response.json()  # 这里直接得到一个 list
    print(f"成功获取 {len(users_data)} 位用户的信息。")
    # 打印第一个用户的姓名和邮箱
    print(f"示例用户: {users_data[0]['name']}, 邮箱: {users_data[0]['email']}")
else:
    print(f"请求失败,状态码: {response.status_code}")
    # 可以尝试打印更多信息,比如错误文本
    # print(response.text)

print("\n" + "="*50 + "\n")

# 2. 发送带查询参数的 GET 请求:获取特定用户的帖子
print("--- 带参数的 GET 请求示例 ---")
user_id = 1
params = {'userId': user_id}
posts_url = "https://jsonplaceholder.typicode.com/posts"
response = requests.get(posts_url, params=params)

if response.status_code == 200:
    posts = response.json()
    print(f"用户 {user_id} 共有 {len(posts)} 篇帖子。")
    # 打印第一篇帖子的标题
    print(f"第一篇帖子标题: {posts[0]['title']}")
else:
    print(f"请求失败,状态码: {response.status_code}")

print("\n" + "="*50 + "\n")

# 3. 发送 POST 请求:模拟创建一篇新帖子
print("--- POST 请求示例 ---")
new_post = {
    'title': '我的新帖子',
    'body': '这是通过 Python 脚本自动创建的内容。',
    'userId': 1
}

# 设置请求头,明确告知服务器我们发送的是 JSON 数据
headers = {'Content-Type': 'application/json'}
response = requests.post(
    "https://jsonplaceholder.typicode.com/posts",
    headers=headers,
    json=new_post  # 直接使用 `json` 参数,它会自动设置序列化和头部
)

# 对于 POST/PUT 请求,成功创建通常返回状态码 201
if response.status_code == 201:
    created_post = response.json()
    print(f"帖子创建成功!新帖子的ID为: {created_post['id']}")
    print(f"返回的数据: {json.dumps(created_post, indent=2, ensure_ascii=False)}")
else:
    print(f"创建失败,状态码: {response.status_code}")
    print(f"错误详情: {response.text}")

实践练习

练习 1:基础数据获取

要求:使用 https://jsonplaceholder.typicode.com/todos 这个 API 端点,获取所有待办事项(todos)。

  1. 发送一个 GET 请求。
  2. 打印总共获取了多少条待办事项。
  3. 打印第一条待办事项的 titlecompleted 字段的值。 预期输出示例
成功获取 200 条待办事项。
第一条: "delectus aut autem", 完成状态: False

练习 2:查询参数过滤

要求:只获取"已完成"(completedTrue)的待办事项。

  1. 查阅 API 文档或测试,了解如何用查询参数进行过滤(提示:在 URL 后加 ?completed=true)。
  2. 使用 params 字典实现。
  3. 打印符合条件的待办事项数量。 预期输出示例
已完成的待办事项共有: 90 条。

练习 3:模拟数据提交与错误处理

要求:模拟向 /comments 端点发送一个无效的 POST 请求,并处理错误。

  1. 构造一个明显不符合 API 要求的请求体(例如,缺少必要字段)。
  2. 发送 POST 请求。
  3. 打印返回的状态码和响应文本。 预期输出示例
请求失败,状态码: 400
错误详情: { ... }  # API返回的错误JSON信息

常见错误

  1. 忘记检查状态码:直接调用 .json()。如果请求失败(如 404, 500),服务器可能返回的不是有效的 JSON(可能是 HTML 错误页面),这会导致 JSONDecodeError

    # 错误做法
    data = response.json()  # 如果 response 不是 200,可能在这里出错
    
    # 正确做法
    if response.status_code == 200:
        data = response.json()
    else:
        print(f"Error: {response.status_code}")
        # 处理错误情况
    
  2. 混淆 .json().text.json() 方法会自动将响应体解析为 Python 对象。如果你手动用 json.loads(response.text),记得处理可能出现的解析异常。

  3. POST/PUT 请求忘记设置 Content-Type:当发送 JSON 数据时,最好明确指定 headers={'Content-Type': 'application/json'},或者更方便地,直接使用 requestsjson 参数(它会自动设置)。

  4. 参数和数据混淆params 用于 URL 查询参数(出现在 ?key=value 后),datajson 用于 请求体(POST/PUT 时发送的主要内容)。

小结

本课我们学习了与 RESTful API 交互的核心流程:

  1. 构建请求:确定目标 URL、HTTP 方法(GET/POST等)、参数(params)和请求体(data/json)。
  2. 发送请求:使用 requests.get()requests.post() 等方法。
  3. 处理响应首先检查状态码,然后使用 .json() 方法解析成功的响应数据为 Python 字典或列表。
  4. 错误处理:对网络错误、无效 JSON、非 2xx 状态码等情况进行优雅处理,增强脚本的健壮性。

掌握这些技能,意味着你能够利用互联网上开放的 API 来获取实时数据、自动化在线服务,这是成为"全栈"或"数据"开发者的关键一步。在下一课,我们将结合 BeautifulSoup 库,学习如何从网页中提取结构化数据。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「网页爬虫基础:requests + BeautifulSoup」 以巩固所学知识。