美文网首页
python的异步初体验(gevent、async、await)

python的异步初体验(gevent、async、await)

作者: 都江堰古巨基 | 来源:发表于2018-10-12 16:34 被阅读0次

    网络爬虫,这种io高密集型的应用由于大部分的时间在等待响应方面,所以CPU的使用率一直不高,速度也不快,为了解决这些问题,我们使用异步的方式来进行爬虫程序。

    串行的时候,如果我们要爬一个网站,那么我们通常都是一页的内容完成了,再到下一页,这样的话,CPU的90%以上的时间用在了等待网页响应上面。

    异步的话,我们可以同时发起多个请求,一个请求发起了之后就不等待这个请求的响应,马上发起第二个请求,第三个请求......
    然后响应过来的内容我们再一个个进行处理,这样的效率就高了很多。

    举个栗子:
    首先我们搭建一个flask的服务器,故意降低它的响应速度:

    from flask import Flask
    import time
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        # 休眠三秒,展示异步的速度
        time.sleep(3)
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run(threaded=True)
    

    首先我们使用python 3.5以上版本的async、await以及异步http请求库aiohttp:

    import asyncio
    import time
    import aiohttp
    
    start = time.time()
    
    async def get(url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as res:
                print(res.status)
                text = await res.text()
                return text
    
    async def hello():
        url = "http://127.0.0.1:5000/"
        print('Waiting for',url)
        res = await get(url)
        print('Result:',res)
    
    loop = asyncio.get_event_loop()
    tasks = [asyncio.ensure_future(hello()) for i in range(5)]
    loop.run_until_complete(asyncio.wait(tasks))
    
    end = time.time()
    print('Cost time:',end-start)
    

    使用python的第三方库:gevent也可以实现网络异步:

    from gevent import monkey
    # 猴子补丁一定要先打,不然就会报错
    monkey.patch_all()
    import gevent
    import requests
    import time
    
    
    def get(url):
        print("Get from: ",url)
        r = requests.session()
        res = r.get(url)
        print(res.status_code,url,res.text)
    
    def synchronous_times(url):
        start = time.time()
        for i in range(5):
            get(url)
        end = time.time()
        print("同步执行的时间:", start-end)
    
    def asynchronous_times(url):
        start = time.time()
        gevent.joinall([gevent.spawn(get,url) for i in range(5)])
        end = time.time()
        print("异步执行的时间:", start-end)
    
    synchronous_times("http://127.0.0.1:5000/")
    asynchronous_times("http://127.0.0.1:5000/")
    

    以上就使用aiohttp、genvent实现了异步的网络请求。

    相关文章

      网友评论

          本文标题:python的异步初体验(gevent、async、await)

          本文链接:https://www.haomeiwen.com/subject/iivtiftx.html