在 Python 众多的 HTTP 客户端中,最有名的莫过于requests、aiohttp和httpx。在不借助其他第三方库的情况下,requests只能发送同步请求;aiohttp只能发送异步请求;httpx既能发送同步请求,又能发送异步请求。

所谓的同步请求,是指在单进程单线程的代码中,发起一次请求后,在收到返回结果之前,不能发起下一次请求。所谓异步请求,是指在单进程单线程的代码中,发起一次请求后,在等待网站返回结果的时间里,可以继续发送更多请求。

今天我们来一个浅度测评,仅仅以多次发送 POST 请求这个角度来对比这三个库的性能。

请求发送的 ts 字段日期距离今天大于10天,那么返回{"success": false},如果小于等于10天,那么返回{"success": true}。

首先我们通过各个客户端使用相同的参数只发送一次请求,看看效果。

1. 发送一次请求

requests

import requests

resp = requests.post('http://122.51.39.219:8000/query',

json={'ts': '2020-01-20 13:14:15'}).json()

print(resp)

运行效果如下图所示:

httpx

使用 httpx 发送同步请求:

import httpx

resp = httpx.post('http://122.51.39.219:8000/query',

json={'ts': '2020-01-20 13:14:15'}).json()

print(resp)

httpx 的同步模式与 requests 代码重合度99%,只需要把requests改成httpx即可正常运行。如下图所示:

使用 httpx 发送异步请求:

import httpx

import asyncio

asyncdef main():

asyncwith httpx.AsyncClient() as client:

resp = await client.post('http://122.51.39.219:8000/query',

json={'ts': '2020-01-20 13:14:15'})

result = resp.json()

print(result)

asyncio.run(main())

运行效果如下图所示:

aiohttp

import aiohttp

import asyncio

asyncdef main():

asyncwith aiohttp.ClientSession() as client:

resp = await client.post('http://122.51.39.219:8000/query',

json={'ts': '2020-01-20 13:14:15'})

result = await resp.json()

print(result)

asyncio.run(main())

运行效果如下图所示:

aiohttp 的代码与 httpx 异步模式的代码重合度90%,只不过把AsyncClient换成了ClientSession,另外,在使用 httpx 时,当你await client.post时就已经发送了请求。但是当使用aiohttp时,只有在awiat resp.json() 时才会真正发送请求。

2. 发送100次请求

我们现在随机生成一个距离今天在5-15天的日期,发送到 HTTP接口中。如果日期距离今天超过10天,那么返回的数据的 False,如果小于等于10天,那么返回的数据是 True。

我们发送100次请求,计算总共耗时。

requests

在前几天的文章中,我们提到,使用requests.post每次都会创建新的连接,速度较慢。而如果首先初始化一个 Session,那么 requests 会保持连接,从而大大提高请求速度。所以在这次测评中,我们分别对两种情况进行测试。

不保持连接

import random

import time

import datetime

import requests

def make_request(body):

resp = requests.post('http://122.51.39.219:8000/query', json=body)

result = resp.json()

print(result)

def main():

start = time.time()

for _ in range(100):

now = datetime.datetime.now()

delta = random.randint(5, 15)

ts = (now - datetime.timedelta(days=delta)).strftime('%Y-%m-%d %H:%M:%S')

make_request({'ts': ts})

end = time.time()

print(f'发送100次请求,耗时:{end - start}')

if __name__ == '__main__':

main()

运行效果如下图所示:

发送100次请求,requests 不保持连接时耗时2.7秒

保持连接

对代码稍作修改,使用同一个 Session 发送请求:

import random

import time

import datetime

import requests

def make_request(session, body):

resp = session.post('http://122.51.39.219:8000/query', json=body)

result = resp.json()

print(result)

def main():

session = requests.Session()

start = time.time()

for _ in range(100):

now = datetime.datetime.now()

delta = random.randint(5, 15)

ts = (now - datetime.timedelta(days=delta)).strftime('%Y-%m-%d %H:%M:%S')

make_request(session, {'ts': ts})

end = time.time()

print(f'发送100次请求,耗时:{end - start}')

if __name__ == '__main__':

main()

运行效果如下图所示:

发送100次请求,requests 保持连接耗时1.4秒

httpx

同步模式

代码如下:

import random

import time

import datetime

import httpx

def make_request(client, body):

resp = client.post('http://122.51.39.219:8000/query', json=body)

result = resp.json()

print(result)

def main():

session = httpx.Client()

start = time.time()

for _ in range(100):

now = datetime.datetime.now()

delta = random.randint(5, 15)

ts = (now - datetime.timedelta(days=delta)).strftime('%Y-%m-%d %H:%M:%S')

make_request(session, {'ts': ts})

end = time.time()

print(f'发送100次请求,耗时:{end - start}')

if __name__ == '__main__':

main()

运行效果如下图所示:

发送100次请求,httpx 同步模式耗时1.5秒左右。

异步模式

代码如下:

import httpx

import random

import datetime

import asyncio

import time

asyncdef request(client, body):

resp = await client.post('http://122.51.39.219:8000/query', json=body)

result = resp.json()

print(result)

asyncdef main():

asyncwith httpx.AsyncClient() as client:

start = time.time()

task_list = []

for _ in range(100):

now = datetime.datetime.now()

delta = random.randint(5, 15)

ts = (now - datetime.timedelta(days=delta)).strftime('%Y-%m-%d %H:%M:%S')

req = request(client, {'ts': ts})

task = asyncio.create_task(req)

task_list.append(task)

await asyncio.gather(*task_list)

end = time.time()

print(f'发送100次请求,耗时:{end - start}')

asyncio.run(main())

运行效果如下图所示:

发送100次请求,httpx 异步模式耗时0.6秒左右。

aiohttp

测试代码如下:

import aiohttp

import random

import datetime

import asyncio

import time

asyncdef request(client, body):

resp = await client.post('http://122.51.39.219:8000/query', json=body)

result = await resp.json()

print(result)

asyncdef main():

asyncwith aiohttp.ClientSession() as client:

start = time.time()

task_list = []

for _ in range(100):

now = datetime.datetime.now()

delta = random.randint(5, 15)

ts = (now - datetime.timedelta(days=delta)).strftime('%Y-%m-%d %H:%M:%S')

req = request(client, {'ts': ts})

task = asyncio.create_task(req)

task_list.append(task)

await asyncio.gather(*task_list)

end = time.time()

print(f'发送100次请求,耗时:{end - start}')

asyncio.run(main())

运行效果如下图所示:

发送100次请求,使用 aiohttp 耗时0.3秒左右

3. 发送1000次请求

由于 request 保持连接的速度比不保持连接快,所以我们这里只用保持连接的方式来测试。并且不打印返回的结果。

requests

运行效果如下图所示:

发送1000次请求,requests 耗时16秒左右

httpx

同步模式

运行效果如下图所示:

发送1000次请求,httpx 同步模式耗时18秒左右

异步模式

运行效果如下图所示:

发送1000次请求,httpx 异步模式耗时5秒左右

aiohttp

运行效果如下图所示:

发送1000次请求,aiohttp 耗时4秒左右

4. 总结一下

如果你只发几条请求。那么使用 requests 或者 httpx 的同步模式,代码最简单。

如果你要发送很多请求,但是有些地方要发送同步请求,有些地方要发送异步请求,那么使用 httpx 最省事。

如果你要发送很多请求,并且越快越好,那么使用 aiohttp 最快。

这篇测评文章只是一个非常浅度的评测,只考虑了请求速度这一个角度。如果你要在生产环境使用,那么你可以做更多实验来看是不是符合你的实际使用情况。

(完)

看完本文有收获?请转发分享给更多人

关注「Python那些事」,做全栈开发工程师

点「在看」的人都变好看了哦

python做客户端适合吗_为了选出最合适的 HTTP 客户端,我做了个测评相关推荐

  1. python做客户端适合吗_太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端...

    原标题:太简单!只学十分钟,Python菜鸟也能开发一个区块链客户端 作者:Adil Moujahid 编译:kou.Eli 本文转自区块链大本营(ID:blockchai_camp),转载需授权 区 ...

  2. python数据分析多久能学会_周末深夜,学妹说她想做Python数据分析师....

    大家好,我是大鹏,目前是一名数据分析师, 上周末晚上,我的学妹突然约我出来喝咖啡,我觉得这件事情不简单,果然一到她就递给我手机,开口就问: 鹏哥,你是个很厉害的数据分析师吧,快帮我看看这招聘要求都是什 ...

  3. 代写python代码一般多少钱_代写CO 353课程作业、代做Python程序设计作业、代写Python语言作业...

    代写CO 353课程作业.代做Python程序设计作业.代写Python语言作业 日期:2020-03-17 11:22 CO 353 - Homework assignment 4 Winter ' ...

  4. sketch如何做设计稿交互_当屏幕可以折叠,交互设计怎么做

    折叠屏终端上市,无形中增加了电商平台的开发运维成本.笔者根据折叠屏的特点,提出了三种交互方案,看看如何在折叠屏上展示界面. 2007年,当乔布斯举着没有物理键盘的iPhone向全世界展示他的新发明时, ...

  5. 第一次做项目经理总结_工程总承包项目:项目经理如果是第一次做,一定要把握这4个要点...

    出品 | 项目经理世界(ID:IPMP_WORLD)全文2280字 老张的下一个项目是EPC项目,对于老张自己来说也算是一个新领域.为了不打无准备之仗,老张申请了EPC培训,对整个EPC项目做了一个全 ...

  6. python做些什么项目内容_现在比较流行的python做什么项目最适合?

    摘要: 现在比较流行的python做什么项目最适合?相对其他语言来说python算是简单易学的编程语言了,同时python又和Java一样是开源免费的,可以在各种不同类型的计算机上运行,w... 现在 ...

  7. python语言适合做什么生意好_学完python可以从事哪些行业?

    随着人工智能和大数据的兴起,Python受到了越来越多人的关注,一跃成为最受欢迎的编程语言之一.Python如此火爆,发展前景怎么样?学完后可以做什么呢?下面,千锋上海带大家了解一下. Python到 ...

  8. python在家创业项目_适合在家创业的项目有哪些 八大项目人人可做

    适合在家创业的项目有哪些 八大项目人人可做 2018-03-06 14:57 [摘要] 在刚开始淘宝兴起的时候,很多人都选择了在家开一家淘宝店,听说之前开淘宝店的现在的生意都非常的不错,所以说抓住机遇 ...

  9. 编程入门python java和c语言_学习编程适不适合从Python入门?哪种语言更适合入门?...

    本文对比了C语言和Python语言,分析它们作为编程入门语言各自的利弊,并给出了我推荐的编程学习道路. 我本身已经入门了Python脚本语言,在进阶C语言和JAVA语言后,Python重学就轻松很多, ...

最新文章

  1. stackoverflow上Java相关回答整理翻译
  2. 支持markdown的服务器,Vuejs中使用markdown服务器端渲染的示例
  3. js 字符ascii码转换函数
  4. DataGridView很详细的用法
  5. 企业效益真的向好么?
  6. dataframe 如何选中某列的一行_PySpark和SparkSQL基础:如何利用Python编程执行Spark(附代码)
  7. 获取本机IP(考虑多块网卡、虚拟机等复杂情况)
  8. C语言的延时程序怎么改,C语言编程,怎么用按键来改变延时的长短?
  9. Netty工作笔记0044---Netty案例源码分析
  10. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(8月20日-8月26日)
  11. 15-1 并发版爬虫架构
  12. comet学习(三)cometd心跳机制
  13. WPF实现竖向排列并换行显示
  14. Buses and People CodeForces 160E 三维偏序+线段树
  15. bazel proxy 设置
  16. MFC的运行过程,TheApp对象
  17. 前端 css 自动生成,关于前端:利用Zeplin从设计图自动生成CSS提高前端样式开发效率...
  18. ps4仁王服务器不稳定,原来《仁王》放弃独占PS4早有预兆 未来将是跨平台大潮...
  19. 什么是MapReduce?MapReduce整体架构搭建使用介绍
  20. 设备防病毒-深信达MCK(云私钥)

热门文章

  1. 圆满收官!我的2022 秋招总结与建议
  2. goto php 源码,GoToPHP
  3. 欢迎访问我的Github
  4. 数学建模-12.预测模型
  5. Kernel Method核方法—基本概念
  6. SpringBoot指南(二)——常用注解及操作
  7. 机器学习之熵【从定义到代码】
  8. 第二天matplotlib绘图
  9. Keil5配置GCC编译器编译STM32工程
  10. python判断字符串,str函数isdigit、isdecimal、isnumeric的区别