Python 有三个众所周知的库用于发送 HTTP(超文本传输协议)请求: HTTPX、AIOHTTP 和 Requests。 所有这些都有其独特的优点和缺点。
通常,您需要对同步 HTTP 请求使用 Requests,在需要同步和异步混合时使用 HTTPX,在只需要异步请求时使用 AIOHTTP。
请求库
请求可能是最流行的 Python 库之一。内置的 "urllib3" 和其他 HTTP 请求库非常复杂且难以解析。 发出请求是为了简化发送 HTTP 请求的过程。
您可以通过 pip 安装库:
python -m pip install requests
安装后, 您需要导入库。 您可以通过添加以请求命名的方法(例如,get; post; delete)来发送各种 HTTP 请求。
import requests
response = requests.get("https://example.com")
print(response.text)
简单性是请求的主要卖点,尤其是与 urllib3 相比。大多数方法和函数都非常直观, 使该库非常适合初学者。
它也经常与 Selenium 等各种浏览器自动化工具结合使用,用于 Python Web 开发。
请求与其他库概要
不幸的是,该库也有一些主要缺点:
-
不支持异步 Requests 用于同步编程。虽然您可以解决此问题,但通常最好选择 HTTPX 或 AIOHTTP 来完成这项工作。
-
不支持 HTTP/2 请求使用 HTTP/1.1,这是协议的较慢版本。当比较 Requests 与 HTTPX 或 AIOHTTP 时,它总是较慢的库。
-
基于 "urllib3" 构建 Requests 继承了 "urllib3" 的所有优点和缺点,因为它是建立在它之上的。随着时间的推移,改进的空间越来越小,即使该图书馆确实得到了大量的社区支持。
HTTPX 库
HTTPX 协议是一个受 Requests 启发的库,但尝试修复与其相关的所有问题。因此, HTTPX 同时提供异步兼容性和 HTTP/2 支持。
这些重大改进使 HTTPX 成为一种流行的库。 此外,由于它受到 Requests 的启发,因此大多数方法和函数都是相同的。
python -m pip install httpx
安装库后,导入它。大多数方法都是相同的 -- 每个 HTTP 请求都是与其名称关联的方法。
import httpx
response = httpx.get("https://example.com")
print(response.text)
异步兼容性遵循发送 HTTP 请求的相当标准的结构。
import httpx
import asyncio
async def fetch(url):
async with httpx.AsyncClient() as client:
response = await client.get(url)
return response.status_code, response.text
async def main():
url = "https://www.example.com"
status_code, content = await fetch(url)
print(f"Status Code: {status_code}")
print(f"Content: {content[:100]}...") # Printing only the first 100 characters
if name == "main":
asyncio.run(main())
虽然您可以将 "asyncio" 与 Requests 一起使用,但它会涉及将同步调用包装在异步包装器中, 这可能不如从头开始使用专为异步 I/O 设计的库有效。
HTTPX 与其他库概要
与任何其他库一样,HTTPX 也有一些缺点:
- 相对较新
将 Requests 与 HTTPX 进行比较时,后者要更新得多。虽然它变得越来越稳定和受到更多支持,但该库仍有很长的路要走。
-
更高的依赖性 HTTPX 的依赖项比请求多,这在最小化依赖项至关重要的环境中可能很重要。
-
学习曲线 HTTPX 具有许多功能,因为它结合了同步和异步兼容性。AIOHTTP 和 Requests 都只关注一个,这使得它们更容易学习。
AIOHTTP 库
最后,HTTPX vs Requests vs AIOHTTP 组的第三个成员是一个仅用于异步编程的库。它构建在 "asyncio" 框架之上,使其成为从头开始异步发送 HTTP 请求的库。
但是,AIOHTTP 与 HTTPX 和 Requests 完全不同。 它有点难以使用,因为发送单个 HTTP 请求需要几行代码。AIOHTTP 开发人员知道 -- 甚至还有一个专门的页面来解释原因.
要开始使用,您需要先安装 AIOHTTP 库:
python -m pip install AIOHTTP
设置整个过程有点复杂,需要一些解释。
import aiohttp
import asyncio
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
print(f"Status: {response.status}")
content = await response.text()
print(f"Body: {content[:100]}...") # Print the first 100 characters of the body
async def main():
url = "https://www.example.com"
await fetch(url)
Run the main function
if name == "main":
asyncio.run(main())
导入库后,我们必须定义一些函数。
"fetch" 函数是我们将发送 GET HTTP 请求的函数。与常规 Python 函数不同, 我们必须包含 "async" 才能使其成为异步函数。
首先,我们必须创建一个 session 对象,它允许我们发送大量具有相同参数的 HTTP 请求。 "Async with" 在退出块后关闭会话,即使发生异常也是如此。部分原因是性能和防泄漏,另一部分是语法糖。
"Async with" 在下一行中执行相同的操作。 但是,我们随后使用 session 对象发送 GET HTTP 请求。
打印输出相对不言自明。但是,内容对象有一个主要区别 -- "await",它会冻结"fetch"函数的实例。 当该调用被冻结时,"fetch" 的其他实例(或其他通常的异步函数)可以并行运行。
因此,Requests 与 AIOHTTP(在某种程度上是 HTTPX)的强大之处在于显而易见的。 使用 AIOHTTP,您可以同时运行多个 HTTP 请求,而不是一个接一个地发送。
AIOHTTP 与其他库概要
与其他库一样,也有一些主要缺点:
- 无同步支持
它不是为同步请求构建的库,因此在比较 Requests 与 AIOHTTP 时,您将前者用于同步,后者用于异步。没有理由不这样做。
- 学习曲线和复杂性
在这三个库中,它是学习最复杂的库。
- 调试困难
在比较大型代码库的 Requests 和 AIOHTTP 时,前者总是比后者更容易调试。
比较 HTTPX 与 AIOHTTP 与 Requests
在所有三个主要 HTTP 请求库之间进行选择时,您应该首先确定您需要同步还是异步兼容性。 任何一个库都将删除其中一个库,留下 Requests vs HTTPX 或 HTTPX vs AIOHTTP。
此外,还要考虑项目范围。 如果需要寄几个用于 Web 抓取的 HTTP 请求或任何其他方式,更简单的库将更好地为您服务,留下 HTTPX vs Requests 可供选择。如果您需要在主要代码库上发送异步 HTTP 请求,只有一个选项 -- AIOHTTP。
最后,优化问题也会影响您在 HTTPX 与 Requests 还是 AIOHTTP 之间进行选择。如果网络速度和性能在您的项目中起着重要作用,那么 HTTPX 与 AIOHTTP 是两种选择。
图书馆 性能 异步兼容性 易用性 学习曲线
请求 慢 无异步 HTTP 请求 最高 最低
HTTPX 协议 中间地带 为 HTTP 请求提供两种类型的兼容性 高,与 Requests 相当 低,与 Requests 相当
AIOHTTP 最好,可与 HTTPX 相媲美 仅为 HTTP 请求提供异步功能 最低 最高