异步爬虫-协程概念、协程相关操作(单线程+异步协程)

一、异步爬虫的方式梳理

  • 1、多线程,多进程(不推荐)
    • 好处 :可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行;
    • 弊端 :无法无限制的开启多线程或者多进程;
  • 2、线程池、进程池(适当使用)
    • 好处 :可以降低系统对进程或者线程创建和销毁的一个频率,从而很好的降低系统的开销;
    • 弊端 :池中线程活进程的数量是有上限的;
  • 3、单线程+异步协程
    • event_loop :事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循还上,当满足某些条件的时候,函数就会被循环执行;
    • coroutine :协程对象,可以将协程对象注册到事件循环中,它会被事件循环调用,可以使用async 关键字来定义一个方法,这个方法在调用时不会立即执行,而是返回一个协程对象;
    • task :任务,它是协程对象的进一步封装,包含了任务的各个状态;
    • future :代表将来执行或者还没有执行的任务,实际上和 task 没有本质区别;
    • asycn :定义一个协程;
    • await :用来挂起阻塞方法的执行;

二、协程相关操作回顾

  • 基本协程使用示例
import asyncio

async def request(url):
    print('正在请求的 url :', url)
    print('请求成功,', url)

# async 修饰后的函数,调用后返回一个协程对象
c = request('www.baidu.com')

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

# 将协程对象注册到事件循环对象中,然后启动循环对象
loop.run_until_complete(c)
  • task 任务的使用示例
import asyncio

async def request(url):
    print('正在请求的 url :', url)
    print('请求成功,', url)

# async 修饰后的函数,调用后返回一个协程对象
c = request('www.baidu.com')

# task 任务对象就是对协程对象的进一步的封装,只不过想协程对象封装到任务对象后,任务对象就可以包含相关的状态信息
# 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 基于loop,创建任务对象,将协程对象封装到任务对象
task = loop.create_task(c)
print(task)
# 将任务对象注册到事件循环对象中,然后启动循环对象
loop.run_until_complete(task)
print(task)

# 执行结果
	<Task pending coro=<request() running at C:/Users/daizhe/Desktop/Python学习/爬虫学习/协程/example.py:5>>
	正在请求的 url : www.baidu.com
	请求成功, www.baidu.com
	<Task finished coro=<request() done, defined at C:/Users/daizhe/Desktop/Python学习/爬虫学习/协程/example.py:5> result=None>
  • future :代表将来执行或者还没有执行的任务,实际上和 task 没有本质区别,使用示例;
import asyncio

async def request(url):
    print('正在请求的 url :', url)
    print('请求成功,', url)

# async 修饰后的函数,调用后返回一个协程对象
c = request('www.baidu.com')

# futrue的使用
# 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 基于携程对象,创建futrue任务对象
task = asyncio.ensure_future(c)
print(task)
# 将任务对象注册到事件循环对象中,然后启动循环对象
loop.run_until_complete(task)
print(task)

# 执行结果
	<Task pending coro=<request() running at C:/Users/daizhe/Desktop/Python学习/爬虫学习/协程/example.py:5>>
	正在请求的 url : www.baidu.com
	请求成功, www.baidu.com
	<Task finished coro=<request() done, defined at C:/Users/daizhe/Desktop/Python学习/爬虫学习/协程/example.py:5> result=None>
  • 绑定回调用示例
import asyncio

async def request(url):
    print('正在请求的 url :', url)
    print('请求成功,', url)
    return url

# async 修饰后的函数,调用后返回一个协程对象
c = request('www.baidu.com')

# 回调函数
def callback_func(task):
    # result 返回的就是任务对象中封装的协程对象对应函数的返回值
    print(task.result())

# 绑定回调
# 创建一个事件循环对象
loop = asyncio.get_event_loop()
# 基于携程对象,创建futrue任务对象
task = asyncio.ensure_future(c)
# 将回调函数绑定到任务对象中
task.add_done_callback(callback_func)
# 将任务对象注册到事件循环对象中,然后启动循环对象
loop.run_until_complete(task)

# 执行结果
	正在请求的 url : www.baidu.com
	请求成功, www.baidu.com
	www.baidu.com
posted @ 2021-05-09 17:41  SRE运维充电站  阅读(208)  评论(0编辑  收藏  举报