想在HTTPX和Requests之间做出选择,以确定哪个是Python的最佳HTTP客户端库吗?下面的文章将对这两者进行比较,以帮助你选择最适合你的。
在之前的一篇文章中,我比较了AIOHTTP和HTTPX。正如你将发现的那样,HTTPX在某些方面(包括API设计、现代性和易用性)看起来和感觉上更像Requests而非AIOHTTP。在本指南中,我希望更进一步,因为那篇文章可能会引发关于Requests和HTTPX之间区别的讨论。
与AIOHTTP的比较不同,由于AIOHTTP同时支持客户端和服务器,因此在使用上略有不同,而在这次比较中,HTTPX和Requests都仅用于编写客户端应用程序。本文将为你解答三个问题,包括这两个库有多相似,它们的区别是什么,以及哪个更适合你的具体使用场景。
什么是HTTPX?
根据HTTPX库官方网站的信息,HTTPX被描述为一个功能齐全的Python 3 HTTP客户端库。这个库专门用于发送HTTP请求,与本文中的对比对象Requests非常相似。然而,它的特点在于支持同步和异步操作,并且支持HTTP/1.1和HTTP/2。
该库还附带一个命令行客户端,使其可以直接从命令行使用而无需编写Python代码,在某些方面可以作为cURL的替代品。它具备一些高级功能,包括JSON/XML序列化、自定义头和认证,以及TLS支持等。即便拥有这些功能,它也可以说是受到了Requests的启发。
什么是Requests Python客户端?
Requests,被广泛称为Python中最受欢迎的第三方HTTP客户端。使用它,你可以自定义并发送HTTP请求。它广泛用于网页抓取和其他形式的自动化。在大多数抓取教程中,Requests通常与BeautifulSoup一起使用,以教导新手如何检索和解析网页文档。然而,它总体上是用于发送网页请求并接收响应。
Requests具有高度的可定制性,可以用于许多任务。它是建立在urllib3之上的。引入Requests是为了简化HTTP请求的处理,因为如果使用Python自带的标准HTTP客户端urllib3,这个过程会非常繁琐。Requests仅支持HTTP/1.1,并且通常是为同步操作开发的。要实现异步操作,需要使用一些变通方法。
HTTPX和Requests的相似之处
在许多情况下,你可以使用它们中的任何一个,并不会有任何区别,因为它们在很多方面都非常相似。让我们来看一下它们相似的一些方面。
API端点设计
两者最显著的相似之处之一就是它们的API设计。它们看起来几乎一样。事实上,对于它们的一些API,你可以互换使用,而不会导致代码出错。举个例子,如果你需要发送一个简单的GET请求。在Requests中,你可以这样做:
import requests
content = requests.get('https://www.google.com').content
print(content)
在HTTPX中,上述操作可以这样实现:
import httpx
content = requests.get('https://www.google.com').content
print(content)
如你所见,唯一的区别在于,在Requests中你导入并使用的是`requests`,而在HTTPX中则是`httpx`。
实际上,看看Requests官网提供的Hello World代码:
现在,再看看HTTPX官网上的相同内容,然后进行比较。
正如你所看到的,似乎一个在模仿另一个。从我们所知的来看,HTTPX是在模仿Requests,因为Requests早于HTTPX出现。然而,这里并不在于谁模仿了谁。你需要注意的是,这两个API在某种程度上是相似的,因此在许多方面是兼容的,用其中一个编写的代码库可以很容易地转换为另一个。
支持请求/响应处理
两者都是HTTP客户端库,可以处理网页请求和响应。重要的是,你要知道它们都是功能齐全的,提供了发送请求和处理响应所需的一切。你可以自定义头信息、提供认证信息、附加cookies、设置代理,甚至更改用户代理等。
在响应处理方面,你可以查询HTTP响应的详细信息和头信息,获取内容可以作为文本,或将其序列化为JSON或XML。有趣的是,它们都无法渲染JavaScript,这使得在不使用变通或复杂方法的情况下无法抓取Ajax化的页面。
HTTPX和Requests之间的区别
现在进入主要目标——区分HTTPX和Requests,以便你可以判断哪个更适合你的项目。它们的区别体现在同步/异步支持、HTTP协议支持、基于流的响应支持、性能、社区和支持等方面。
同步和异步支持
通常,对于小型项目,你可以一个接一个地发送网络请求。然而,对于大型项目,你需要一次发送尽可能多的请求。然而,这在Python中并不是开箱即用的功能。
Requests是从头开始构建为同步的,因为主线程会被阻塞,直到一个请求完成后才允许执行另一个请求。如果你想使用Requests进行异步网络访问,你必须使用一些变通方法,这涉及使用asyncio模块和一些技巧。
另一方面,HTTPX是从头开始使用asyncio模块构建为异步的。这意味着HTTPX比Requests更适合异步操作,因为它默认支持这种功能。它也能完美地与其他基于asyncio模块的库和工具(如aiomysql)一起工作。
有趣的是,它不仅仅是为异步操作而构建的,还为了兼容性和那些从Requests模块迁移过来的用户提供了同步操作的支持。
HTTP协议版本
当前的HTTP版本是HTTP/2。然而,并不是所有的HTTP客户端都支持或已经迁移到这个版本。那么HTTPX和Requests在这方面的情况如何呢?Requests模块基于HTTP/1.1版本,尚未迁移。而HTTPX则支持HTTP/1.1和HTTP/2版本,使其更符合最新版本的标准。
这些版本(HTTP/1.1和HTTP/2)听起来像是行话——对于非技术人员来说确实如此。然而,实际上,HTTP/2是HTTP的改进版本,因为它解决了一些HTTP/1.1的众多问题。
使用HTTP/2,你可以获得对多路复用连接的支持,允许你通过单个TCP连接发送多个请求。它基于二进制协议,与基于文本格式的HTTP/1.1相比,允许更好的数据解析和处理。HTTP/2在其他方面的改进还包括流优先级、服务器推送和头信息压缩。
性能
性能是你需要关注的重要特性。如果你有一个大型项目或时间性是应用程序中的重要因素,那么性能就显得尤为重要。两种客户端库在性能方面都表现良好。不过,也可以说在这方面仍有改进的空间。
然而,当涉及到发送多个请求时,HTTPX表现得更好。考虑到HTTPX的异步特性,Requests根本无法与之相比,HTTPX的速度要快得多。
那么,在同步操作方面的性能如何呢?根据“Confession of a Data Guy”的文章,HTTPX在这方面也略快于Requests。这部分归功于其对HTTP/2的支持以及其他现代技术的应用。
根据测试,当同步发送大约50个请求时,HTTPX的平均响应时间约为0.72秒,并且有相当数量的请求低于这个时间。而对于Requests,平均响应时间约为0.74秒。考虑到HTTPX的异步特性,你可以看出Requests在性能方面无法与HTTPX匹敌。
社区和支持
在受欢迎程度、社区和支持方面,有一个HTTP客户端库占据主导地位,那就是Requests。它最初于2011年2月14日发布,是下载量最多的,每月下载量超过3亿。它大约有52K颗星、9.3K次分叉,以及超过1.3K人在关注。在StackOverflow上非常受欢迎,几乎没有Python自动化开发者没用过它。
虽然它最初不是由Python软件基金会编写的,但现在已移交给他们,并且相比于Python标准库中的urllib3,它受到了更多关注。因此,当你需要帮助时,你会很快得到帮助和解答,因为社区相当庞大。
然而,HTTPX在这方面不是一个强有力的竞争者。这是因为它相对较新,于2019年发布。目前,它大约有800次分叉、13K颗星,以及大约115名开发者在关注。
除了涉及异步编程的指南外,你很少能看到使用Python的HTTPX进行抓取教程或发送网络请求的教程。它不如Requests那么受欢迎,已经使用它的开发者数量也较少。不过,它相对容易上手,因此如果有需要,可以让Requests的用户转向使用它。
如何选择合适的库?
这两个库都是处理HTTP请求和响应的优秀客户端库。在大多数情况下,你可以使用其中任何一个,你的项目都会运行良好。然而,在某些情况下,你可能会因为一个库的优势而选择使用它。让我们看看如何为你选择最佳的库。
性能
如果你的项目需要高性能,特别是在每个请求的时间和发送并发请求的能力方面,那么使用HTTPX模块会更好。虽然如果你决定使用Requests,有一种变通方法,但这并不是它的设计初衷——它是为同步操作而设计的。
另一方面,HTTPX模块是为此而构建的,因为它从头开始就与Asyncio模块集成,并且与其他使用Asyncio的库更好地集成。使用HTTPX,你可以同时发送更多请求,相比Requests获得性能提升。
支持和易用性
最易用的库是Requests。两者的API都很相似。然而,关于Requests的讨论、问题、答案和专家比HTTPX要多。Requests还得到了Python软件基金会的支持,使其成为更稳固和受欢迎的选择。
此外,大多数工作岗位都期望你会使用Requests,只有一些特定用例的职位会期望你将HTTPX作为工具之一。由于HTTPX借鉴了Requests的API,可以说HTTPX的团队看到了其简单性,并不想改变任何新的东西。
因此,可以说如果易用性和社区支持对你很重要,你应该选择Requests。
现代性
你想要的是实用的,还是使用现代技术的?如果你想要的是实用的,那么你可以选择任意一个,因为它们都能正常工作并完成任务。然而,如果你需要的是更现代的、采用最新技术和实践的库,那么你应该选择HTTPX。
Requests库虽然实用且更受欢迎,但仍然停留在旧的方式上——它仅支持HTTP/1.1,基于urllib3,并且尚未准备好转变,因为它目前提供的功能对大多数用户来说已经足够。
然而,HTTPX是最近才实现的,因此它能够结合一些新的实践和技术,其中最显著的是支持HTTP/2,这使得通信更加优化和快速。
项目需求
你的项目需求也是选择的一个重要因素。如果你的项目明确规定了要使用的库,你就必须遵循这一规定。在没有明确要求的情况下,你可以寻找提示。例如,如果你的项目要求使用HTTP/2以支持多路复用,你就知道Requests不是一个选项,因为它不支持这一点。
然而,你知道HTTPX完全支持这一点。同样重要的是你的项目是否需要异步操作。
结 论
从以上内容可以看出,这两个库中没有一个是万能的选择。它们都能正常工作,并能完成大多数任务。然而,虽然Requests较老,拥有更大的社区和更好的支持,HTTPX则较新,能更好地整合最新的实践,并支持异步操作。最终,你需要选择最适合你用例的那个,而不是我认为这两个中最酷的那个。

