多任务异步操做在爬虫中的应用

首先来了解几个概念 :python

  • event_loop:事件循环,至关于一个无限循环,咱们能够把一些函数注册到这个事件循环上,当知足某些条件的时候,函数就会被循环执行。程序是按照设定的顺序从头执行到尾,运行的次数也是彻底按照设定。当在编写异步程序时,必然其中有部分程序的运行耗时是比较久的,须要先让出当前程序的控制权,让其在背后运行,让另外一部分的程序先运行起来。当背后运行的程序完成后,也须要及时通知主程序已经完成任务能够进行下一步操做,但这个过程所需的时间是不肯定的,须要主程序不断的监听状态,一旦收到了任务完成的消息,就开始进行下一步。loop就是这个持续不断的监视器。app

  • coroutine:中文翻译叫协程,在 Python 中常指代为协程对象类型,咱们能够将协程对象注册到事件循环中,它会被事件循环调用。咱们可使用 async 关键字来定义一个方法,这个方法在调用时不会当即被执行,而是返回一个协程对象。异步

  • task:任务,它是对协程对象的进一步封装,包含了任务的各个状态。async

  • future:表明未来执行或尚未执行的任务,实际上和 task 没有本质区别。函数

  • 另外咱们还须要了解 async/await 关键字,它是从 Python 3.5 才出现的,专门用于定义协程。其中,async 定义一个协程,await 用来挂起阻塞方法的执行. oop

1.获取一个协程对象 :url

#基本使用
import asyncio
async def hello(name):    #需使用async关键字
    print('hello to :',name)
#获取了一个协程对象
c = hello('xiaohua')

#建立一个事件循环对象
loop = asyncio.get_event_loop()

#将协程对象注册到事件循环中,而后启动事件循环对象
loop.run_until_complete(c)  # hello to : xiaohua

2.task的使用spa

import asyncio
async def hello(name):
    print('hello to :',name)

c = hello('xiaohua')
loop = asyncio.get_event_loop()
#就协程进行进一步的封装,封装到了task对象中
task = loop.create_task(c)
print(task)
loop.run_until_complete(task)
print(task)

#<Task pending coro=<hello() running at D:/untitled/practice.py:612>>   待执行
#hello to : xiaohua
#<Task finished coro=<hello() done, defined at D:/untitled/practice.py:612> result=None>  执行完毕

 

3.future的使用翻译

import asyncio

async def hello(name):
    print('hello to :',name)

c = hello('xiaohua')
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)

loop.run_until_complete(task)

#hello to : xiaohua

4.回调函数的使用协程

import asyncio
def callback(task): print('i am callback:',task.result()) async def hello(name): print('hello to :',name) return name c = hello('xiaohua') loop = asyncio.get_event_loop() task = asyncio.ensure_future(c) #给任务对象绑定一个回调函数 task.add_done_callback(callback) loop.run_until_complete(task) #hello to : xiaohua #i am callback: xiaohua

5.多任务异步协程示例

import asyncio, time

async def request(url):
    print('正在下载:', url)
    #     sleep(2) #非异步模块的代码:在此处若是存在非异步操做代码,则会完全让asyncio失去异步的效果
    await asyncio.sleep(2)   #经过await关键字实现手动挂起
    print('下载成功:', url)

urls = [
    'www.baidu.com',
    'www.taobao.com',
    'www.sogou.com'
]
start = time.time()
loop = asyncio.get_event_loop()
tasks = []  # 任务列表,放置多个任务对象
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(c)
    tasks.append(task)

# 将多个任务对象对应的列表注册到事件循环中
loop.run_until_complete(asyncio.wait(tasks))
print('总耗时:', time.time() - start)

结果 : 

  正在下载: www.baidu.com
  正在下载: www.taobao.com
  正在下载: www.sogou.com
  下载成功: www.baidu.com
  下载成功: www.taobao.com
  下载成功: www.sogou.com
  总耗时: 2.0026607513427734

相关文章
相关标签/搜索