Python案例:如何发送HTTP请求?从入门到实战详解
目录导读
- 为什么需要发送HTTP请求?
- Python发送HTTP请求的常用库对比
- 使用标准库urllib发送GET请求
- 使用第三方库requests发送POST请求
- 处理JSON响应与错误状态码
- 问答:常见问题与解决方案
- 实战总结与最佳实践
为什么需要发送HTTP请求?
在当今互联网时代,几乎所有应用程序都需要与远程服务器交互数据,无论是调用RESTful API获取天气信息、提交表单数据,还是抓取网页内容,发送HTTP请求都是Python开发者的核心技能,根据Stack Overflow 2024年开发者调查,超过68%的Python开发者定期处理HTTP请求。

Python发送HTTP请求的常用库对比
| 库名 | 特点 | 适用场景 |
|---|---|---|
urllib |
Python内置,无需安装 | 简单请求、标准库依赖 |
requests |
语法简洁,功能强大 | 绝大多数项目首选 |
aiohttp |
异步支持,高性能 | 高并发场景 |
httpx |
现代异步/同步双模 | 需要HTTP/2支持 |
其中requests库因其优雅的API设计和完善的文档,成为最广泛使用的选择。
使用标准库urllib发送GET请求
import urllib.request
import json
# 发送GET请求
url = "https://api.example.com/data"
try:
with urllib.request.urlopen(url) as response:
# 读取响应内容
data = response.read().decode('utf-8')
json_data = json.loads(data)
print(f"成功获取数据:{json_data}")
except urllib.error.HTTPError as e:
print(f"HTTP错误:{e.code}")
except urllib.error.URLError as e:
print(f"URL错误:{e.reason}")
关键点:
- 使用
urlopen时需要处理可能的异常需手动解码为字符串 - 适合不需要复杂功能的基础场景
使用第三方库requests发送POST请求
首先安装requests库:
pip install requests
然后编写POST请求代码:
import requests
import json
# 定义请求URL和表单数据
url = "https://httpbin.org/post"
payload = {
"username": "python_user",
"action": "login",
"timestamp": "2024-01-15T10:30:00Z"
}
headers = {
"Content-Type": "application/json",
"User-Agent": "PythonClient/1.0"
}
try:
# 发送POST请求
response = requests.post(url,
data=json.dumps(payload),
headers=headers,
timeout=5)
# 检查响应状态
if response.status_code == 200:
result = response.json()
print(f"请求成功!服务器返回:{result}")
else:
print(f"请求失败,状态码:{response.status_code}")
except requests.exceptions.Timeout:
print("请求超时,请检查网络连接")
except requests.exceptions.ConnectionError:
print("连接失败,目标服务器可能不可达")
except requests.exceptions.RequestException as e:
print(f"请求异常:{e}")
核心优势:
- 自动处理JSON序列化(使用
json=payload参数更简洁) - 内置超时和异常处理机制
- 响应自动解码,无需手动操作
处理JSON响应与错误状态码
实际开发中,我们需要根据不同的HTTP状态码做出不同处理:
import requests
from requests.exceptions import HTTPError
def fetch_api_data(api_url, api_key):
"""安全获取API数据的通用函数"""
headers = {"Authorization": f"Bearer {api_key}"}
try:
response = requests.get(api_url, headers=headers, timeout=10)
# 使用raise_for_status自动抛出异常
response.raise_for_status()
# 解析JSON响应
data = response.json()
return data
except HTTPError as http_err:
if response.status_code == 401:
print("认证失败,请检查API密钥")
elif response.status_code == 404:
print("请求的资源不存在")
elif response.status_code == 500:
print("服务器内部错误,请稍后重试")
else:
print(f"HTTP错误:{http_err}")
except requests.exceptions.Timeout:
print("请求超时,建议重试")
except ValueError as json_err:
print(f"JSON解析失败:{json_err}")
return None
# 使用示例
api_response = fetch_api_data("https://jsonplaceholder.typicode.com/posts/1",
"your_api_token_here")
if api_response:
print(f"获取到的标题:{api_response['title']}")
问答:常见问题与解决方案
Q1:如何发送带参数的GET请求?
A:使用params参数:
params = {"page": 1, "limit": 20}
response = requests.get("https://api.example.com/items", params=params)
Q2:如何处理SSL证书验证错误?
A:设置verify=False(仅用于测试环境):
response = requests.get("https://untrusted-host.com", verify=False)
生产环境建议使用verify="/path/to/cert.pem"指定自定义证书。
Q3:如何发送带cookie的请求?
A:直接传入cookies字典或使用Session对象:
session = requests.Session()
session.cookies.set("session_id", "abc123")
response = session.get("https://example.com/profile")
Q4:请求频繁被限制怎么办?
A:添加请求头模拟真实浏览器,并控制请求频率:
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
time.sleep(1) # 每次请求间隔1秒
实战总结与最佳实践
- 首选requests库:对于99%的场景,requests足以胜任,且代码可读性远超urllib
- 始终处理异常:网络请求的失败率往往高于预期,务必捕获所有可能的异常类型
- 设置合理超时:不设置timeout会导致程序在无响应时永久阻塞
- 使用会话重用连接:频繁请求同一网站时,使用Session对象可复用TCP连接,提升效率
- 避免硬编码敏感信息:API密钥、密码等应通过环境变量或配置文件管理
通过以上案例和最佳实践,你现在可以自信地在Python项目中发送HTTP请求,无论是简单的数据获取还是复杂的API交互,都能游刃有余,建议在实际项目中从简单请求开始,逐步增加错误处理和优化逻辑,形成稳固的HTTP通信组件。