多任务,异步的实现需要理解7个概念,如下表。
说明 | 创建和使用 | |
---|---|---|
特殊函数 | 1.不是立即返回,2返回的是协程 | c = get_request("http://127.0.0.1:5000/test") |
协程 | 协程对象==特殊函数 | |
任务 | 任务==协程对象 | task = asyncio.ensure_future(c) |
事件 | 用来装载任务的对象。相当于一个容器用来装载事件对象。 | loop = asyncio.get_event_loop() 创建一个事件循环对象 loop.run_until_complete(task)将task存储到事件中 |
回调函数 | 1.定义回调函数 把task做为参数放在函数里;函数返回值:task.result() 2.绑定回调函数 task.add_done_callback(parse) | def parse(task): page_text=task.result() print("i am task callbask!") |
挂起 | await() | |
aiohttp | aiohttp 则是基于asyncio 实现的HTTP框架使用上与request类似,只proxy="http://ip:port"与request不一样 | with aiohttp.ClientSession() as sess: sess.get(url,headers,params,proxy) sess.post(url,headers,data,proxy) with sess.get(url=url) as response: page_text=response.text() |
特殊函数不可以出现不支持异步的模块async 每个with前加async 每个阻塞前加await |
上代码:
#特殊函数 做了修改 不可以出现不支持异步模块的代码,不可以使用requests模块
#添加 async
async def get_request(url):
async with aiohttp.CientSession() as sess:
async with await sess.get(url=url) as response:
page_text=await response.text()
return page_text
def parse(task):
page_text=task.result()
tree=etree.HTML(page_text)
data_text=tree.xpath('//a[@id="feng"]/text()')[0]
print("i am task callbask!")
def multfuns():
urls=[
'http://127.0.0.1:5000/test1',
'http://127.0.0.1:5000/test2',
'http://127.0.0.1:5000/test3'
]
tasks=[]
for url in urls:
c=get_request(url)
task = asyncio.ensure_future(c)
task.add_done_callback(parse)
tasks.append(task)
loop=asyncio.get_event_loop()
#将多任务注册到事件循环中
# loop.run_until_complete(tasks)
loop.run_until_complete(asyncio.wait(tasks))
if __name__=="__main__":
multfuns()