asyncio

直接内置了对异步IO的支持。

asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。

flask服务

from flask import Flask
import time
​
app = Flask(__name__)
​
​
@app.route('/bobo')
def index_bobo():
    time.sleep(2)
    return 'Hello bobo'
​
@app.route('/jay')
def index_jay():
    time.sleep(2)
    return 'Hello jay'
​
@app.route('/tom')
def index_tom():
    time.sleep(2)
    return 'Hello tom'if __name__ == '__main__':
    app.run(threaded=True)

 

async/await的特点

1.async/await更加语义化,async是'异步'的缩写,async function 用于声明一个function是异步的;
  await,可以认为是async wait的缩写,用于等待一个异步方法执行完成; 2.async/await是一个用同步思维解决异步问题的方案(等结果出来后代码才会继续执行) 3.可以通过多层async function的同步写法代替传统的callback嵌套

 

多任务异步爬虫

import asyncio 
import time
import aiohttp  #异步请求模块,requests不能异步请求
start = time.time()
#在特殊函数内部不可以出现异步模块相关的代码
#注意细节:
    #1.在每一个with前加上async关键字
    #2,在get方法前和response.text()前加上await关键字进行手动挂起操作
async def request(url):
    async with aiohttp.ClientSession() as s:
        #s.get/post和request中的get/post用法几乎一样:url,heasers,data/prames
        #在s.get中如果使用代理:proxy="http://ip:port"是个字符串,而requests中是个字典
        async with await s.get(url) as response: #有阻塞的地方加上await,手动挂起
            # 获取字符串形式的响应数据:response.text()
            # 获取byte类型的:response.read()
            page_text=await response.text()
            return page_text
​
urls=[]
for i in range(500):
    urls.append('http://127.0.0.1:5000/bobo')
​
def back(task):  #接收执行任务的对象
    page_text=task.result()   #任务对象.result()获得任务函数的返回值
    print(page_text)
​
tasks=[]
for url in urls:
    c=request(url)
    task=asyncio.ensure_future(c)   #创建任务对象
    task.add_done_callback(back)  #添加回调函数,在任务执行完会执行回调函数,可以进行数据分析
    tasks.append(task)#将任务添加到任务列表中 
​
loop=asyncio.get_event_loop() #创建事件循环对象
loop.run_until_complete(asyncio.wait(tasks)) #将任务对象注册到该对象中,并且启动时间循环,加上挂起操作,否则会导致阻塞
print(time.time()-start)    

----------------
3.090151786804199
#500个请求只需3秒,而每个请求还有2秒的io
 
posted @ 2019-08-07 21:07  百鬼之主  阅读(549)  评论(0编辑  收藏  举报