文章目录
- 一、快速对比
- 二、安装
- 三、requests 基本用法
- 常用参数
- 会话(Session)—— 保持连接和 Cookie
- 四、httpx 基本用法(同步)
- 使用 Client(推荐,类似 Session)
- 五、httpx 异步用法(重要优势)
- 六、常见实战功能
- 1. 超时设置
- 2. 认证
- 3. 文件上传
- 4. 代理
- 5. 处理响应
- 七、错误处理
- 八、最佳实践建议
在 Python 中发送 HTTP 请求,最常用的两个库是requests(经典同步库)和httpx(现代支持同步 + 异步的库)。两者 API 高度相似,但设计理念和功能有所不同。
一、快速对比
| 特性 | requests | httpx |
|---|---|---|
| 同步请求 | ✅ 原生支持 | ✅ 支持 |
| 异步请求 | ❌ 不支持 | ✅ 原生支持 |
| HTTP/2 | ❌ | ✅ 支持 |
| API 风格 | 简单易用 | 高度兼容 requests,更现代 |
| 连接池 / 超时 | 支持 | 支持(更灵活) |
| 官方维护状态 | 成熟稳定 | 活跃开发 |
| 推荐场景 | 简单脚本、同步项目 | 新项目、需要异步、HTTP/2 |
建议:
- 新项目优先考虑httpx
- 维护老项目或只需要简单同步请求,继续用requests即可
二、安装
pipinstallrequests pipinstallhttpx# 如果需要 HTTP/2 支持(httpx)pipinstallhttpx[http2]三、requests 基本用法
importrequests# GET 请求response=requests.get("https://httpbin.org/get",params={"key":"value"})print(response.status_code)# 200print(response.text)# 文本内容print(response.json())# 解析 JSON# POST 请求response=requests.post("https://httpbin.org/post",json={"name":"Alice","age":25},# 自动设置 Content-Type: application/jsonheaders={"User-Agent":"MyApp/1.0"})# 其他常用方法requests.put(url,data=...)requests.delete(url)requests.patch(url)requests.head(url)常用参数
response=requests.get(url,params={"page":1},# 查询参数headers={"Authorization":"Bearer xxx"},timeout=10,# 超时(秒)allow_redirects=True,# 是否允许重定向verify=True,# SSL 证书验证)会话(Session)—— 保持连接和 Cookie
session=requests.Session()session.headers.update({"User-Agent":"MyApp/1.0"})session.get("https://example.com/login")response=session.get("https://example.com/profile")# 自动携带 Cookie四、httpx 基本用法(同步)
httpx 的同步 API 几乎可以无缝替换 requests:
importhttpx# GETresponse=httpx.get("https://httpbin.org/get",params={"key":"value"})print(response.status_code)print(response.text)print(response.json())# POSTresponse=httpx.post("https://httpbin.org/post",json={"name":"Alice"},headers={"User-Agent":"MyApp/1.0"})使用 Client(推荐,类似 Session)
withhttpx.Client(timeout=10.0,headers={"User-Agent":"MyApp/1.0"})asclient:response=client.get("https://httpbin.org/get")print(response.json())Client会自动管理连接池,性能更好,也支持上下文管理器。
五、httpx 异步用法(重要优势)
importhttpximportasyncioasyncdefmain():asyncwithhttpx.AsyncClient()asclient:response=awaitclient.get("https://httpbin.org/get")print(response.status_code)print(response.json())# 并发请求tasks=[client.get("https://httpbin.org/get"),client.get("https://httpbin.org/ip"),client.get("https://httpbin.org/user-agent"),]responses=awaitasyncio.gather(*tasks)forrinresponses:print(r.status_code)asyncio.run(main())异步适合:
- 高并发爬虫
- 同时请求多个 API
- FastAPI / 异步 Web 服务中调用外部接口
六、常见实战功能
1. 超时设置
# requestsrequests.get(url,timeout=5)# 总超时requests.get(url,timeout=(3,10))# 连接超时, 读取超时# httpxhttpx.get(url,timeout=5.0)httpx.get(url,timeout=httpx.Timeout(5.0,connect=3.0))2. 认证
# Basic Authrequests.get(url,auth=("user","pass"))httpx.get(url,auth=("user","pass"))# Bearer Tokenheaders={"Authorization":"Bearer your_token"}3. 文件上传
# requests / httpx 写法几乎相同files={"file":open("test.txt","rb")}response=requests.post(url,files=files)4. 代理
proxies={"http://":"http://127.0.0.1:7890","https://":"http://127.0.0.1:7890",}requests.get(url,proxies=proxies)httpx.get(url,proxies=proxies)5. 处理响应
response=httpx.get(url)response.status_code response.headers response.text# 字符串response.content# 字节response.json()# 字典response.raise_for_status()# 状态码不是 2xx 时抛异常七、错误处理
importhttpxtry:withhttpx.Client(timeout=10)asclient:response=client.get("https://httpbin.org/status/404")response.raise_for_status()# 抛出 HTTPStatusErrorexcepthttpx.HTTPStatusErrorase:print(f"HTTP 错误:{e.response.status_code}")excepthttpx.RequestErrorase:print(f"请求失败:{e}")excepthttpx.TimeoutException:print("请求超时")requests的异常体系类似(requests.HTTPError、requests.Timeout等)。
八、最佳实践建议
- 生产环境优先用
Client/Session,而不是每次调用顶层的get()/post() - 必须设置超时,避免请求无限挂起
- 使用
response.raise_for_status()快速发现 HTTP 错误 - 需要并发时,直接上httpx + asyncio
- 请求头统一管理(User-Agent、Authorization 等)
- 敏感信息(Token、密码)不要硬编码,用环境变量或配置管理
- 大型项目可封装一个统一的 HTTP 客户端类
简单封装示例(httpx):
importhttpxfromtypingimportAnyclassHttpClient:def__init__(self,base_url:str,token:str|None=None):headers={"User-Agent":"MyApp/1.0"}iftoken:headers["Authorization"]=f"Bearer{token}"self.client=httpx.Client(base_url=base_url,headers=headers,timeout=15.0)defget(self,path:str,**kwargs)->Any:response=self.client.get(path,**kwargs)response.raise_for_status()returnresponse.json()defclose(self):self.client.close()🚀 感谢阅读!想了解更多?
📖 我的博客网站 | 记录思考,分享干货
🏡 我的个人主页 | 关于我、开源项目