第 3 章 · POST 与请求体构建
本章目标:掌握 POST、PUT、DELETE 等请求方法,学会构建 JSON 表单和多部分表单请求体。
3.1 HTTP 方法一览
除了 GET,常用的 HTTP 方法还有:
| 方法 | 用途 | 幂等性 |
|---|---|---|
| GET | 获取资源 | ✅ |
| POST | 创建资源/提交数据 | ❌ |
| PUT | 全量更新资源 | ✅ |
| PATCH | 部分更新资源 | ❌ |
| DELETE | 删除资源 | ✅ |
| HEAD | 获取响应头(无 body) | ✅ |
| OPTIONS | 查询支持的方法 | ✅ |
python
import requests
base = 'https://httpbin.org'
# GET - 获取
resp = requests.get(f'{base}/get')
# POST - 创建
resp = requests.post(f'{base}/post', json={'key': 'value'})
# PUT - 全量更新
resp = requests.put(f'{base}/put', json={'key': 'value'})
# PATCH - 部分更新
resp = requests.patch(f'{base}/patch', json={'key': 'value'})
# DELETE - 删除
resp = requests.delete(f'{base}/delete')3.2 JSON 请求体
现代 API 普遍使用 JSON 格式传输数据。requests 提供 json 参数:
python
import requests
# 方法一:使用 json 参数(推荐,自动设置 Content-Type)
resp = requests.post(
'https://httpbin.org/post',
json={'name': '张三', 'age': 30, 'tags': ['python', 'ai']}
)
print(resp.json()['json']) # {'name': '张三', 'age': 30, ...}
# 方法二:手动序列化(适用于需要自定义 Content-Type 的场景)
import json
resp = requests.post(
'https://httpbin.org/post',
data=json.dumps({'name': '张三'}),
headers={'Content-Type': 'application/json'}
)json 参数会自动:
- 将 Python 对象序列化为 JSON 字符串
- 设置
Content-Type: application/json请求头
3.3 表单请求体
传统的 HTML 表单使用 application/x-www-form-urlencoded 格式:
python
import requests
# 表单数据(自动编码)
resp = requests.post(
'https://httpbin.org/post',
data={'username': 'admin', 'password': 'secret123'}
)
# 查看发送的数据
print(resp.json()['form']) # {'username': 'admin', 'password': 'secret123'}3.4 文件上传
使用 files 参数上传文件,支持单文件和多文件:
python
import requests
# 上传单个文件
with open('report.pdf', 'rb') as f:
resp = requests.post(
'https://httpbin.org/post',
files={'document': f}
)
# 上传多个文件
files = [
('photos', ('a.jpg', open('a.jpg', 'rb'), 'image/jpeg')),
('photos', ('b.jpg', open('b.jpg', 'rb'), 'image/jpeg')),
]
resp = requests.post('https://httpbin.org/post', files=files)
# 自定义文件名和内容类型
resp = requests.post(
'https://httpbin.org/post',
files={
'file': ('custom_name.txt', b'file content', 'text/plain')
}
)files 参数接受多种格式:
- 文件对象:
{'file': open('x.pdf', 'rb')} - 元组:
{'file': ('name.ext', content, 'mime/type')}
3.5 组合请求体
实际场景中,可能同时需要表单字段和文件:
python
import requests
# 表单字段 + 文件
resp = requests.post(
'https://httpbin.org/post',
data={'title': '报告', 'category': '技术'},
files={'document': open('report.pdf', 'rb')}
)
# 复杂场景:多个文件 + 字段
files = [
('attachments', ('doc1.pdf', open('doc1.pdf', 'rb'), 'application/pdf')),
('attachments', ('doc2.pdf', open('doc2.pdf', 'rb'), 'application/pdf')),
]
data = {
'project': 'Alpha',
'description': '季度报告',
'priority': 'high'
}
resp = requests.post('https://example.com/upload', data=data, files=files)3.6 httpx 的等效写法
httpx 的 API 与 requests 高度一致:
python
import httpx
# POST with JSON
resp = httpx.post('https://httpbin.org/post', json={'key': 'value'})
# POST with form data
resp = httpx.post('https://httpbin.org/post', data={'key': 'value'})
# File upload
with open('file.txt', 'rb') as f:
resp = httpx.post('https://httpbin.org/post', files={'file': f})3.7 本章小结
- POST/PUT/PATCH/DELETE 方法与 requests 对应函数名相同;
- JSON 请求体用
json参数,自动序列化并设置 Content-Type; - 表单数据用
data参数,文件上传用files参数; - httpx 语法与 requests 高度兼容。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. requests.post() 的 json 参数和 data 参数有什么区别?
2. 以下哪种方式可以正确上传文件?
3. PUT 和 PATCH 方法的主要区别是?
4. httpx 上传文件时,files 参数的格式与 requests 相比?
🛠️ 动手实践
- 用 POST 向
https://httpbin.org/post发送 JSON 数据,打印返回的 JSON 字段。 - 上传一个文本文件到 httpbin,查看服务器接收的文件名和内容。
- 组合表单字段和文件上传,模拟一个"提交带附件的表单"场景。