Python requests库代码示例:发送GET与POST网络请求
本文详解使用 Python requests 库发送 GET 与 POST 网络请求的具体方法与完整代码示例,涵盖 URL 参数传递、Form 与 JSON 载荷提交、请求头设置、超时控制及异常处理。
在 Python 中进行网络数据采集、调用第三方 REST API 或进行自动化接口测试时,requests 库是应用最广泛的 HTTP 客户端工具。相较于 Python 内置的 urllib 模块,requests 提供了更贴合人类直觉的 API 封装,能够用极短的代码行数完成连接建立、参数编码、请求发送及响应解析。本文将围绕网络交互中最常用的两类操作——GET 与 POST 请求,通过具体的代码示例拆解其实际用法、参数传递差异、头信息定制与异常处理逻辑。
一、前置准备与快速验证
在开始编写代码前,确保运行环境中已经安装了 requests。该库不属于 Python 标准库,需要使用包管理工具安装:
pip install requests
在终端或 Python 脚本中验证安装是否成功:
import requests
print(requests.__version__)
若输出了具体的版本号(例如 2.31.0),说明运行环境已就绪。在日常开发中,建议统一通过 import requests 进行模块引入。
二、发送 GET 请求:获取网络资源与传递查询参数
GET 请求用于从指定的服务器获取资源。按照 HTTP 规范,GET 操作是安全的和幂等的,意味着发起请求不会改变服务器端的数据状态。
1. 基础 GET 请求示例
最简单的 GET 请求只需向 requests.get() 传入目标 URL。以下代码请求一个公开的测试接口并打印响应结果:
import requests
# 目标地址(示例使用公共测试接口)
url = "https://httpbin.org/get"
# 发送 GET 请求
response = requests.get(url)
# 查看响应状态码与文本内容
print("状态码:", response.status_code)
print("返回文本内容:", response.text)
在上述代码中,requests.get() 返回一个 Response 对象。通过该对象,可以提取状态码、响应体、响应头等关键信息。
2. 携带 URL 查询参数(params)
许多 API 需要通过 URL 传递筛选、分页或关键词信息,例如 https://example.com/search?keyword=python&page=1。若手动用字符串格式化拼接,容易出现中文乱码或特殊符号转义错误。requests 提供了 params 参数,允许直接传入 Python 字典,库内部会自动处理 URL 编码:
import requests
url = "https://httpbin.org/get"
# 定义查询参数字典
query_params = {
"keyword": "网络爬虫",
"page": 2,
"sort": "desc"
}
# 传入 params 参数
response = requests.get(url, params=query_params)
# 查看最终请求的实际 URL
print("最终请求 URL:", response.url)
# 示例输出: https://httpbin.org/get?keyword=%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB&page=2&sort=desc
print("解析出的 JSON 数据:", response.json())
3. 定制请求头 Headers 与设置超时 Timeout
在默认情况下,requests 发出的 HTTP 请求头中的 User-Agent 会包含 python-requests/x.x.x 字样。很多服务器为了防止自动化爬虫,会直接屏蔽或拦截带有此特征的请求。因此,在发送请求时配置请求头是一个标准做法。同时,若目标服务器无响应,未指定超时的请求可能会无限期阻塞程序,务必通过 timeout 明确限制等待秒数:
import requests
url = "https://httpbin.org/get"
# 伪装为常规浏览器的请求头
custom_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "application/json"
}
try:
# 设置超时时间为 5 秒(连接和读取合计上限)
response = requests.get(url, headers=custom_headers, timeout=5)
# 状态码为 200 表示成功
if response.status_code == 200:
data = response.json()
print("请求成功,服务器识别到的 User-Agent:", data["headers"]["User-Agent"])
else:
print(f"请求未成功,状态码为: {response.status_code}")
except requests.exceptions.Timeout:
print("错误:请求连接超时,请检查网络或目标服务器可用性")
三、发送 POST 请求:提交表单数据与 JSON 负载
POST 请求用于向服务器提交数据,通常用于用户登录、表单提交、创建文章或触发某个耗时操作。与 GET 请求将参数暴露在 URL 中不同,POST 请求的数据包含在 HTTP 请求正文(Body)中。在实践中,最常见的两种数据格式为:表单格式(Form Data) 与 JSON 格式(JSON Payload)。
1. 提交表单数据(使用 data 参数)
当模拟传统的 HTML <form> 提交或部分旧版 API 时,数据通常以 application/x-www-form-urlencoded 编码格式传输。在 requests.post() 中,只需将字典赋值给 data 参数:
import requests
url = "https://httpbin.org/post"
# 表单键值对
form_data = {
"username": "developer_test",
"operation": "login",
"remember_me": "true"
}
# 提交表单数据
response = requests.post(url, data=form_data)
# httpbin 会将接收到的表单原样在 form 字段中回显
result = response.json()
print("服务器接收到的表单内容:", result.get("form"))
此时,requests 会自动在请求头中加入 Content-Type: application/x-www-form-urlencoded,并将字典按 key1=value1&key2=value2 的格式编码至请求正文中。
2. 提交 JSON 格式数据(使用 json 参数)
现代前后端分离应用与微服务架构的 RESTful API,绝大多数采用 application/json 格式交互。若将字典手动用 json.dumps() 转换再传给 data,还必须手动补充请求头 Content-Type: application/json。而 requests 专门提供了 json 参数,只需传入原始 Python 字典或列表,库会自动完成序列化并设置匹配的头部:
import requests
url = "https://httpbin.org/post"
# 复杂嵌套结构的字典
json_payload = {
"order_id": 98231,
"user_id": 1042,
"items": [
{"sku": "A101", "quantity": 2, "price": 49.9},
{"sku": "B205", "quantity": 1, "price": 120.0}
],
"is_paid": False
}
# 使用 json 参数直接提交
response = requests.post(url, json=json_payload)
result = response.json()
print("服务器解析出的 JSON 实体:", result.get("json"))
print("客户端实际发送的 Content-Type:", result["headers"].get("Content-Type"))
# 输出中可以看到 Content-Type 自动被设置为 application/json
四、核心响应处理与异常防御
发送请求仅仅是网络调用的前半段,能否稳健地处理服务器返回的信息、正确识别异常,直接决定了程序的可用性。
1. 响应状态检查:raise_for_status()
初学者容易直接读取 response.text,若服务器返回了 404 Not Found 或 500 Internal Server Error,代码后续逻辑便可能出现解析崩溃。标准做法是在提取内容前调用 response.raise_for_status():若状态码为 4xx 或 5xx,它会主动抛出 requests.exceptions.HTTPError 异常:
import requests
url = "https://httpbin.org/status/404"
try:
response = requests.get(url, timeout=5)
# 若返回非 200 系列成功状态,立刻触发异常
response.raise_for_status()
print("请求成功:", response.text)
except requests.exceptions.HTTPError as err:
print(f"HTTP 状态异常: {err}")
print(f"具体错误码: {response.status_code}")
2. 字符集编码与乱码处理
当获取 HTML 或中文接口内容时,偶尔会遇到中文显示为乱码(例如 \xe4\xbd\xa0...)。这是因为 response.text 是根据响应头中的 Content-Type 字符集推断出来的;如果服务端未明确指定编码,requests 可能会默认按照 ISO-8859-1 解码。解决方法是使用 apparent_encoding:
import requests
response = requests.get("https://example.com", timeout=5)
# 若中文显示异常,使用字符检测模块推断的编码
response.encoding = response.apparent_encoding
print(response.text)
3. 会话保持(requests.Session)
如果业务流程需要先登录、后查询,或者需要连续发送数十次请求,直接使用 requests.get() 会为每个请求重新建立底层 TCP 连接,且无法跨请求保持 Cookie。使用 requests.Session() 对象可以复用底层连接池,大幅提升高频请求效率,并自动在多次请求间维护 Cookie 状态:
import requests
# 创建会话对象
session = requests.Session()
# 为整个会话统一配置全局 Header
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppClient/1.0"
})
# 第一次请求:模拟登录或设置 Cookie
session.get("https://httpbin.org/cookies/set/token/abc123xyz")
# 第二次请求:自动带上之前保存的 Cookie
res = session.get("https://httpbin.org/cookies")
print("会话中当前维持的 Cookies:", res.json())
# 使用完毕后关闭会话释放连接池资源
session.close()
五、常用参数与方法速查表
在编写业务代码时,可参考下表根据实际场景选择正确的函数和入参形式:
| 功能需求 | 调用函数 / 参数 | 底层协议行为 | 典型应用场景 |
|---|---|---|---|
| 查询/获取数据 | requests.get(url, params=d) |
数据编码并追加于 URL 末尾 | 搜索列表、获取用户资料、分页读取 |
| 提交 Form 表单 | requests.post(url, data=d) |
Content-Type 为 urlencoded | 旧式 Web 页面表单提交、账号密码登录 |
| 提交 JSON 实体 | requests.post(url, json=d) |
Content-Type 为 application/json | 现代 RESTful API 交互、创建复杂实体 |
| 客户端防封禁伪装 | headers={"User-Agent": "..."} |
替换 HTTP 请求标头 | 所有外网或爬虫场景 |
| 防止程序假死 | timeout=10 |
设置连接与读取超时上限(秒) | 生产级自动化程序标准配置 |
| 多请求连接复用 | s = requests.Session() |
复用 TCP 连接池并自动管理 Cookie | 多步骤连续调用、批量抓取接口 |
实战要点总结:进行 HTTP 请求时,记住“读用 GET、写用 POST;URL 拼参用 params,接口提交用 json;超时 timeout 必配置,响应校验 raise_for_status 不可少”。遵循这几项规范,即可写出健壮、高效且具备良好容错能力的 Python 网络请求代码。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













