关于封装了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倍,几乎越多请求异步操作的优势也就越明显。所以今天介绍的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等待,提升整个业务性能。

时间: 2024-10-12 08:25:14

关于封装了gevent的request grequest库的使用与讨论的相关文章

封装自己的Common.js工具库

Code/** * Created by LT on 2013/6/16. * Common.js * 对原生JS对象的扩展 * Object.Array.String.Date.Ajax.Cookie */ ;(function(){ Object.extend =function(targetObj,fnJson){ for(var fnName in fnJson){ targetObj[fnName]=fnJson[fnName]; } return targetObj; }; /**

python爬虫入门request 常用库介绍

什么是爬虫? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. 其实通俗的讲就是通过程序去获取web页面上自己想要的数据,也就是自动抓取数据. 你可以爬去妹子的图片,爬取自己想看看的视频..等等你想要爬取的数据,只要你能通过浏览器访问的数据都可以通过爬虫获取 爬虫的本质 模拟浏览器打开网页,获取网页中我们想要的那部分数据 浏览器打开网页的过程

vue封装组件,类似elementUI组件库打包发布到npm上

封装vue组件库的两种方法和形式: 一:是建立一个webpack-simple 项目 二:是在通过vue-cli脚手架建立webpack vue项目,这种项目有点冗余,可是我们对这种项目最熟悉 下面分别介绍两种用法: 一: 1.首先先建立一个vue项目: 通过vue init webpack-simple,新建项目目录如下: 箭头指的是在项目打包后产生的文件(打包命令npm run build ) 2.在src下新建一个目录用来存放组件源码: 然后写封装的组件,比如radios/radio.vu

将自己写的组件封装成类似element-ui一样的库,可以cdn引入

在写好自己的组件之后 第一步 修改目录结构 在根目录下创建package文件夹,用于存放你要封装的组件 第二部 在webpack配置中加入 pages与publicpath同级 pages: { index: { entry: 'src/main.js', template: 'public/index.html', filename: 'index.html' } }, 第三部 编写组件 在package文件夹下 新建一个你的组件名的文件夹 里面存放一个你的组件的.vue文件 再新建一个js文

request请求库

安装 pip install requests 测试接口 http://httpbin.org/get get请求 响应对象 = requests.get(......) ? **参数:** ? url: ? headers = {} ? cookies = {} ? params = {} ? proxies = {'http':‘http://端口:ip’}    代理ip 格式固定 ? timeout = 0.5                                    超出时

linux下把log4cxx封装成so动态库文件(一)

这是一个经常遇到的问题,在软件开发过程中,需要将某些功能封装成一个独立的模块,这样维护升级也很方便.现在我们就要把开源日志库log4cxx封装成so动态加载库文件. 在上一篇文章<log4cxx日志库RedHat下安装>中,我们已经将log4cxx安装在home/mac/log4cxx/log4cxx下了,那么接下来的操作我们就继续在这个路径下进行. 还是先tree一下/home/mac/log4cxx这个目录吧 log4cxx ---apr ---apr-util ---log4cxx 那再

Drf04 / drf request请求对象封装、版本、认证、权限

目录 Drf04 / drf request请求对象封装.版本.认证.权限 回顾和补充 今日详细 1.请求的封装 2.版本 3.认证(面试) 4.权限 Drf04 / drf request请求对象封装.版本.认证.权限 回顾和补充 restful规范 1. 建议用https代替http 2. 在URL中体现api,添加api标识 https://www.cnblogs.com/xwgblog/p/11812244.html # 错误 https://www.cnblogs.com/api/xw

网站后端_Flask-第三方库.利用Flask-Socketio扩展构建实时流应用?

模块简介: 说明: 此模块主要用于构建支持实时,双向基于事件的通信,将Websocket和Polling等其它实时通信方式封装成了通用接口,从而可在各个平台/浏览器/设备上稳定工作. 快速安装: pip install flask-socketio <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> 应用场景: 1. 实时分析, 服务端将数据推送到客户端,客户端可以为实时计数器,图表,

17、第七周-网络编程 - 协程概念介绍、协程gevent模块并发爬网页

协程,又称微线程,纤程.什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置. 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销(注解:"原子操作(atomic operation)是不需要synchr