1. 什么是 httpx? #
httpx 是 Python 的一个 HTTP 客户端库,用来向网站或 API 发送请求、接收响应。你可以把它理解为「用代码访问网页」的工具。
为什么学 httpx?
- 如果你用过
requests,httpx 的用法几乎一样,上手很快 - httpx 支持异步,适合需要同时发起多个请求的场景
- 由 Starlette、Uvicorn 等知名项目的团队维护,文档和生态都很好
2. 前置知识 #
在学 httpx 之前,建议先了解这些概念:
HTTP 请求与响应
- 你打开浏览器访问网页,本质是浏览器向服务器发「请求」,服务器返回「响应」
- 常见请求方式:
GET(获取数据)、POST(提交数据) - 响应里有「状态码」:200 表示成功,404 表示未找到,500 表示服务器错误
JSON
- 一种常见的数据格式,长得像 Python 的字典
- 很多 API 用 JSON 返回数据,httpx 可以自动把响应解析成 Python 字典
3. 安装 #
在命令行中执行:
pip install httpx安装完成后,在 Python 里用 import httpx 即可使用。
4. 第一个请求:发送 GET #
GET 是最常用的请求方式,用来「获取」数据。
# 导入 httpx 库
import httpx
# 向 httpbin.org 的 /get 接口发送 GET 请求
# httpbin.org 是一个专门用来测试 HTTP 请求的网站
response = httpx.get("https://httpbin.org/get")
# 打印响应状态码(200 表示成功)
print("状态码:", response.status_code)
# 打印响应的文本内容(原始字符串)
print("响应内容:", response.text[:200], "...")
# 如果响应是 JSON 格式,可以用 .json() 转成 Python 字典
data = response.json()
print("解析后的数据:", data.get("url"))运行方式:把上述代码保存为 demo.py,在终端执行 python demo.py。
5. 理解响应对象 #
每次请求都会得到一个 Response 对象,常用属性和方法如下。
# 导入 httpx
import httpx
# 发送 GET 请求
response = httpx.get("https://httpbin.org/get")
# 状态码:200 成功,404 未找到,500 服务器错误
print("状态码:", response.status_code)
# 响应头:服务器返回的元信息,如 Content-Type
print("Content-Type:", response.headers.get("content-type"))
# 响应体文本(字符串)
print("文本长度:", len(response.text))
# 响应体二进制(bytes),适合非文本内容
# content = response.content
# 若响应是 JSON,自动解析为字典或列表
data = response.json()
print("JSON 中的 url:", data.get("url"))6. 带查询参数的 GET 请求 #
访问 https://example.com/search?q=python 时,? 后面的 q=python 就是查询参数。用 httpx 可以这样写:
# 导入 httpx
import httpx
# 定义查询参数(会拼接到 URL 的 ? 后面)
params = {"name": "张三", "age": 18}
# params 会自动编码,中文等特殊字符会正确处理
response = httpx.get("https://httpbin.org/get", params=params)
# 查看最终请求的 URL
print("实际请求的 URL:", response.url)
# 查看服务器收到的参数
data = response.json()
print("服务器收到的参数:", data.get("args"))7. 发送 POST 请求(提交数据) #
POST 用来向服务器「提交」数据,例如表单、JSON 等。
7.1 提交 JSON 数据 #
很多 API 要求用 JSON 格式提交数据。
# 导入 httpx
import httpx
# 要提交的数据(字典格式)
json_data = {"name": "小明", "age": 20}
# 使用 json= 参数,httpx 会自动转为 JSON 并设置正确的 Content-Type
response = httpx.post("https://httpbin.org/post", json=json_data)
# 查看服务器收到的数据
result = response.json()
print("服务器收到的 JSON:", result.get("json"))7.2 提交表单数据 #
表单数据格式为 field1=value1&field2=value2,常用于网页表单。
# 导入 httpx
import httpx
# 表单数据(键值对)
form_data = {"username": "admin", "password": "123456"}
# 使用 data= 参数,会按表单格式编码
response = httpx.post("https://httpbin.org/post", data=form_data)
# 查看服务器收到的表单数据
result = response.json()
print("服务器收到的表单:", result.get("form"))8. 自定义请求头 #
请求头可以携带额外信息,例如 User-Agent、Authorization 等。
# 导入 httpx
import httpx
# 自定义请求头
headers = {
"User-Agent": "MyApp/1.0", # 标识客户端
"Accept": "application/json", # 希望服务器返回 JSON
}
# 通过 headers= 传入
response = httpx.get("https://httpbin.org/headers", headers=headers)
# 服务器会回显收到的请求头
data = response.json()
print("服务器收到的请求头:", data.get("headers", {}).get("User-Agent"))9. 使用 Client 复用连接 #
如果要对同一个网站发起多次请求,建议使用 Client,可以复用连接、设置默认参数,效率更高。
# 导入 httpx
import httpx
# 使用 with 语句,自动管理连接的打开和关闭
# base_url 会作为所有请求的前缀
with httpx.Client(base_url="https://httpbin.org") as client:
# 请求 /get,实际访问 https://httpbin.org/get
r1 = client.get("/get")
print("第一次请求状态码:", r1.status_code)
# 请求 /post,实际访问 https://httpbin.org/post
r2 = client.post("/post", json={"key": "value"})
print("第二次请求状态码:", r2.status_code)10. 超时设置 #
网络不稳定时,请求可能一直不返回。设置超时可以避免程序卡死。
# 导入 httpx
import httpx
# timeout=5 表示最多等待 5 秒,超时则抛出异常
# 下面请求会延迟 2 秒返回,在 5 秒内,所以能成功
response = httpx.get("https://httpbin.org/delay/2", timeout=5.0)
print("请求成功:", response.status_code)
# 若请求超过 5 秒未返回,会抛出 httpx.TimeoutException11. 错误处理 #
状态码 4xx、5xx 表示请求失败,但 httpx 默认不会抛异常。可以用 raise_for_status() 在失败时主动抛出异常。
# 导入 httpx
import httpx
# 访问一个会返回 404 的地址
response = httpx.get("https://httpbin.org/status/404")
# 此时 response.status_code 是 404,但程序不会报错
print("状态码:", response.status_code)
# 调用 raise_for_status():若状态码为 4xx 或 5xx,会抛出异常
try:
response.raise_for_status()
except httpx.HTTPStatusError as e:
print("请求失败:", e.response.status_code)12. 调用一个公开 API #
下面是一个完整示例:调用 httpbin.org 的接口,完成 GET、POST,并做简单错误处理。
# 导入 httpx
import httpx
def main():
# 使用 Client 复用连接
with httpx.Client(base_url="https://httpbin.org", timeout=10.0) as client:
# 1. 发送 GET 请求
r = client.get("/get", params={"hello": "world"})
r.raise_for_status()
print("GET 成功:", r.json().get("args"))
# 2. 发送 POST 请求
r = client.post("/post", json={"name": "httpx 入门"})
r.raise_for_status()
print("POST 成功:", r.json().get("json"))
if __name__ == "__main__":
main()13. 异步请求简介 #
异步适合「同时发起多个请求」的场景,例如同时请求多个接口。需要配合 async/await 使用。
前置知识:若不了解 async/await,可先跳过本节,用同步方式即可满足大部分需求。
# 导入 httpx 和 asyncio
import httpx
import asyncio
async def fetch():
# 使用 AsyncClient,方法前要加 await
async with httpx.AsyncClient() as client:
response = await client.get("https://httpbin.org/get")
print(response.json().get("url"))
# 用 asyncio.run 运行异步函数
asyncio.run(fetch())并发请求示例:同时请求多个地址,等待全部完成。
# 导入 httpx 和 asyncio
import httpx
import asyncio
async def fetch_all():
async with httpx.AsyncClient() as client:
# 创建三个请求任务(此时尚未真正发送)
tasks = [
client.get("https://httpbin.org/delay/1"),
client.get("https://httpbin.org/delay/2"),
client.get("https://httpbin.org/get"),
]
# 并发执行,等待全部完成
responses = await asyncio.gather(*tasks)
for r in responses:
print(r.url, r.status_code)
asyncio.run(fetch_all())14. 常见问题 #
14.1 如何跟随重定向? #
默认会自动跟随重定向。若不想跟随,可设置 follow_redirects=False:
# 导入 httpx
import httpx
# 不跟随重定向,直接拿到 302 等响应
response = httpx.get("https://httpbin.org/redirect/1", follow_redirects=False)
print("状态码:", response.status_code) # 30214.2 如何设置 Cookie? #
通过 cookies 参数传入字典即可:
# 导入 httpx
import httpx
# 在请求中附带 Cookie
response = httpx.get(
"https://httpbin.org/cookies",
cookies={"session_id": "abc123", "user": "tom"}
)
print(response.json())15. 总结 #
- httpx 是 Python 的 HTTP 客户端,用法类似 requests
- 常用方法:
httpx.get()、httpx.post(),参数有params、json、data、headers等 - 推荐用
Client做多次请求,并设置timeout - 用
raise_for_status()在失败时抛出异常 - 需要并发时,可使用
AsyncClient和asyncio.gather