Python网络请求库,从 requests 到 httpx

· 代码经验

在Python开发者里,requests 一直是大家最常用来发HTTP请求的工具,因为它用起来特别简单,基本上不用查文档就能直接上手;不过现在越来越多项目开始用异步写法,而且大家也想要更快的速度和对新协议(比如HTTP/2)的支持,所以一个新的库 httpx 就出现了,它不仅能像 requests 那样做普通的同步请求,还直接支持异步操作,并且自带连接池、HTTP/2这些更高级的功能,这篇文章就通过一些代码例子来对比这两个库的基本用法,帮你轻松地从 requests 换到功能更强的 httpx

1. 基础的同步请求操作

当你只需要发简单的HTTP请求时,两个库的写法非常接近,迁移起来几乎不用改什么。

requests

import requests

# 发起一个 GET 请求
response = requests.get("https://httpbin.org/get")
print(response.status_code)
print(response.json())

# 发起一个 POST 请求
payload = {"key": "value"}
response = requests.post("https://httpbin.org/post", json=payload)
print(response.json())

httpx(同步模式)

import httpx

# 发起一个 GET 请求
resp = httpx.get("https://httpbin.org/get")
print(resp.status_code)
print(resp.json())

# 发起一个 POST 请求
payload = {"key": "value"}
resp = httpx.post("https://httpbin.org/post", json=payload)
print(resp.json())

2. 利用客户端实现高效通信

如果你要连续发送多个请求,用客户端对象可以复用同一个网络连接(也就是连接池),这样能省下建立新连接的时间,让程序跑得更快。

requests 的会话(Session)

import requests

with requests.Session() as session:
    session.headers.update({"User-Agent": "my-app/1.0"})
    
    first_resp = session.get("https://httpbin.org/get")
    second_resp = session.post("https://httpbin.org/post", json={"hello": "world"})
    
    print(first_resp.status_code, second_resp.status_code)

httpx 的客户端(Client)

import httpx

with httpx.Client() as client:
    client.headers.update({"User-Agent": "my-app/1.0"})
    
    first_resp = client.get("https://httpbin.org/get")
    second_resp = client.post("https://httpbin.org/post", json={"hello": "world"})
    
    print(first_resp.status_code, second_resp.status_code)

3. 异步请求:httpx 的核心优势

这是 httpx 最突出的地方,因为 requests 本身完全不支持异步,而 httpx 提供了一套和同步写法差不多的异步接口,学起来很容易。

httpx 的异步客户端示例

import asyncio
import httpx

async def fetch_data(client: httpx.AsyncClient, url: str) -> dict:
    resp = await client.get(url)
    return resp.json()

async def main():
    endpoints = [
        "https://httpbin.org/get?param=1",
        "https://httpbin.org/get?param=2",
        "https://httpbin.org/get?param=3",
    ]
    
    async with httpx.AsyncClient() as client:
        # 同时发多个请求
        coroutines = [fetch_data(client, url) for url in endpoints]
        all_results = await asyncio.gather(*coroutines)
        
        for item in all_results:
            print(item["args"])

# 运行异步程序
if __name__ == "__main__":
    asyncio.run(main())

这段代码展示了怎么让多个网络请求一起跑,而不是一个接一个地等,对于爬网页或者调很多外部服务的场景,这样做速度能快很多,而用 requests 就只能顺序执行,没法并行。

4. 进阶功能:对HTTP/2协议的支持

httpx 是目前少数几个原生支持HTTP/2的Python客户端之一,它能利用多路复用等技术进一步减少延迟、提升效率。

import httpx

# 开启 HTTP/2
with httpx.Client(http2=True) as client:
    response = client.get("https://http2.pro/")
    print(f"Using HTTP/{response.http_version}")
    # 输出: Using HTTP/2

要启用这个功能,你需要额外安装带HTTP/2支持的版本,命令是 pip install httpx[http2]

如果你只是写一些简单的脚本,不需要并发,那 requests 依然够用又稳定;但一旦你的项目需要用到异步框架(比如 FastAPI 或 Starlette)、要同时处理大量请求,或者想试试更新的网络协议,那么 httpx 就是一个更好的选择,它既保留了熟悉的用法,又带来了更强的能力,值得你花点时间切换过去。