关于封装了gevent的request grequest库的使用与讨论
最近迷上了gevent所以研究很多gevent相关的东西。
但是我现在不想写相关gevent和greenlet的东西。因为这一块内容实在太多太大太杂,我自己也还没有完全弄明白,所以等我完全搞清楚测试也测试过了之后。我会写一篇比较系统一点的东西来把我最近研究,和测试过的东西都展现出来。
今天先写一个基于gevent开发的requests库,grequests的使用。
为什么会有地方使用到grequests呢?
首先是对io密集型的需求处理。首先我们都知道,如我们去请求一个网站上的数据,正常来说我们会一条一条的跑,例如这样。
import requests url = 'http://www.baidu.com'
x = request.get(url)
print x
如果是多个网站的请求 我们可能会使用一个循环以此遍历list url对象。
但是这样就会造一个常见的性能问题。例如中间有一个请求卡住了,或者一些情况导致一个请求长时间没有返回,由于我们的同步请求模式,在得到返回之前我们可能会长时间处于一个io阻塞的状态。这样显而易见,如果有100个请求,不管是性能还是效率肯定都是慢得没得说的。
于是我们才会想要用一种并行的思路去解决类似的问题。如果我们同时开启100个请求,那么最差的情况也就等最后返回的那个家伙返回就可以结束所有的请求了。性能提升是n倍,几乎越多请求异步操作的优势也就越明显。但是这里就要注意了,一般我们不会同步开启那么多请求去访问,因为如果我们开启那么多访问去同时命中对方一台服务器(假设是自己的生产服务器)那么会造成非常大的压力,所以这里我们还可以设置map()的参数将size这个决定并行数量的参数设置成你认为合理的并行值即可。
rs = (grequests.get(u, proxies=proxies) for u in urls)
grequests.map(rs, size=10)
但是要注意一点,由于python里面的全局锁的关系,并不推荐使用多线程这样的伪并行的方式。虽然coroutines也是伪并行的方式(即线性请求,当其中一个请求遇到io等待的时候切换到另外一个coroutines继续运行等到io返回之后再接收信息,避免长时间的等待和阻塞)所以今天介绍的grequests库就可以在python里使用gevent基于coroutines(协程)解决这个问题。
这里演示使用代码,异常简单就可以使你的请求性能提升数倍。
import grequests
import requests
import cProfile urls = [
'http://www.xiachufang.com/downloads/baidu_pip/2016030101.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030102.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030103.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030104.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030105.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030106.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030107.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030108.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030109.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030110.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030111.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030112.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030113.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030114.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030115.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030116.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030117.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030118.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030119.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030120.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030121.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030122.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030123.json',
'http://www.xiachufang.com/downloads/baidu_pip/2016030200.json',
]
def haha(urls):
rs = (grequests.get(u) for u in urls)
return grequests.map(rs) cProfile.run("haha(urls)") def hehe(urls):
hehe = [requests.get(i) for i in urls]
return hehe cProfile.run("hehe(urls)")
下面贴出请求所用时间数据 仅供参考。
使用异步在24个请求的平均耗时测试10次计算 平均花费130毫秒
2/1 0.000 0.000 0.132 0.132 coventry.py:651(haha)
在使用同步普通的request库请求的情况下 同样测试10次 平均花费900毫秒 如果中途遇到有单个链接不稳或者超时甚至会花费1秒
2/1 0.000 0.000 1.149 1.149 coventry.py:657(hehe)
总结:
在io密集,等待io时间长的请求量级越大的情况,这样的性能提升越是明显,使用并发或者协程至少提升性能5倍以上我们越是应该使用异步或并行操作来减少io的等待时间。python比较有效和高效的处理方案我觉得非coroutines(协程)莫属了,而相关库最好用的又是gevent,所以非常值得深入研究下去,一探究竟。使用类似操作减少io等待,提升整个业务性能。
refrence:
http://stackoverflow.com/questions/16015749/in-what-way-is-grequests-asynchronous
http://johndangerthornton.blogspot.com/2015/02/grequests-examples.html
http://stackoverflow.com/questions/21978115/using-grequests-to-make-several-thousand-get-requests-to-sourceforge-get-max-r
关于封装了gevent的request grequest库的使用与讨论的更多相关文章
- Gevent高并发网络库精解
进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程.多线程.协程和异步. 多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库 多线程 ...
- Python3使用request/urllib库重定向问题
禁止自动重定向 python3的urllib.request模块发http请求的时候,如果服务器响应30x会自动跟随重定向,返回的结果是重定向后的最终结果而不是30x的响应结果. request是靠H ...
- 简单方便统一封装的傻瓜式GET/POST库AliasNet正式公布~开源喽~
在进行网页自动化时我们做得最多的工作就是不停的往某个URL GET/POST数据并得到相应的Response,通过分析Response的结果再进行下一步操作,通过网页自动化我们可以做很多工作,比如去某 ...
- 3-STM32带你入坑系列(自己封装点亮一个灯的库--Keil)
2-STM32带你入坑系列(点亮一个灯--Keil) 首先建一个stm32f103x.h的文件,然后 #include "stm32f103x.h" 还记得上一节 现在呢就是做一个 ...
- libxl库的介绍,对Excel操作封装得很好的一个库,兼容2007版和多字节字符(最后有破解版下载)
前段时间忙着毕业论文,终于有时间写博客了. 早些时候老大给我的一个任务需要对excel进行读表操作,研究了一下c++对excel的操作. 对Excel的操作基本有com,ODBC,AD等,其中ODBC ...
- 将自己写的组件封装成类似element-ui一样的库,可以cdn引入
在写好自己的组件之后 第一步 修改目录结构 在根目录下创建package文件夹,用于存放你要封装的组件 第二部 在webpack配置中加入 pages与publicpath同级 pages: { in ...
- 封装自己的Common.js工具库
Code/** * Created by LT on 2013/6/16. * Common.js * 对原生JS对象的扩展 * Object.Array.String.Date.Ajax.Cooki ...
- 封装caffe版的deeplab为库供第三方使用
1.解决deeplab编译问题 http://m.2cto.com/kf/201612/579545.html
- Protel封装库
一.目录下面的一些封装库中,根据元件的不同封装我们将其封装分为二大类:一类是分立元件的封装,一类是集成电路元件的封装 1.分立元件类: 电容:电容分普通电容和贴片电容: 普通电容在Miscellane ...
随机推荐
- java-深克隆和浅克隆
文章参考 https://www.cnblogs.com/acode/p/6306887.html 一.前提 1.使用clone()方法的类,必须实现Cloneable接口, 否则调用clone()方 ...
- MATLAB——LMS算法(△规则Delta Rule)
- 深入浅出的webpack构建工具--webpack4+vue搭建环境 (十三)
深入浅出的webpack构建工具--webpack4+vue搭建环境 (十三) 从上面一系列的webpack配置的学习,我们现在来使用webpack来搭建vue的开发环境.首先我们来设想下我们的项目的 ...
- Objective-C 实现读写锁
读写锁 @interface RWLock : NSObject - (void)readLock; - (void)readUnlock; - (void)writeLock; - (void)wr ...
- C语言程序设计II—第九周教学
第九周教学总结(22/4-28/4) 教学内容 本周的教学内容为: 9.1 输出平均分最高的学生信息 知识点:结构的概念.结构的定义形式.结构的嵌套定义.结构变量和结构成员变量的引用.重难点:结构变量 ...
- WebSphere下配置HTTP压缩
WebSphere下配置HTTP压缩 背景 WebSphere本身的安装配置中并不包含HTTP压缩的模块,而是通过新增WebServer来实现的,WebSphere通过Plugin与WebServer ...
- UVA1265 Tour Belt Kruskal重构树、倍增、树上差分
题目传送门 题意:定义$Tour \, Belt$为某张图上的一个满足以下条件的点集:①点集中至少有$2$个点②任意两点互相连通③图上两个端点都在这个点集中的边的权值的最小值严格大于图上只有一个端点在 ...
- angularjs的$window功能小练习
我们想在一个文本框输入一些文字,然后点击铵钮,alert()出来. <div ng-app="alertApp" ng-controller="alertContr ...
- ES6 Promise 异步操作
最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢? 一.小插曲(气氛搞起) 在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的 ...
- Caffe源码中caffe.proto文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下caffe.proto文件. 在src/caffe/proto目录下有一个 ...