多任务异步协程,asyncio及aiohttp

要实现异步协程,需要满足几个条件:

  1,创建协程对象,且协程内部操作需要支持异步。

  2,创建任务对象,如需为协程执行结果进行进一步处理,则需要为任务对象绑定回调函数。

  3,创建事件循环,并将任务启动。

 1 import asyncio
 2 import requests
 3 from lxml import etree
 4 import aiohttp
 5 import os
 6
 7 headers = {
 8
 9     ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36‘
10 }
11
12
13 # 普通单线程,同步执行任务
14 # url_ = ‘https://www.qiushibaike.com/pic/page/{}/‘
15 # for i in range(1, 100):
16 #     url = url_.format(i)
17 #
18 #     ret = requests.get(url=url, headers=headers).text
19 #     tree = etree.HTML(ret)
20 #     url_list = tree.xpath(‘//div[@id="content-left"]/div/div/a/img/@src‘)
21 #     for url in url_list:
22 #         name = url.split(‘/‘)[-1]
23 #         print(name)
24 #         img_url = ‘https:‘ + url
25 #         img = requests.get(img_url, headers=headers).content
26 #         with open(os.path.join(‘qiutu‘,name), ‘wb‘) as f:
27 #             f.write(img)
28
29 # 使用async修饰过的函数,调用函数时,函数不执行,而是生成了一个协程对象
30 async def get_img(url):
31     """
32     # aiohttp的细节处理:
33     # asnyc:硬性的语法要求关键字,应用aiohttp的代码模块
34     # await: 会出现阻塞的操作的代码中,需要用await修饰
35
36     """
37
38     # ret = requests.get(url=url, headers=headers).text
39     name = url.split(‘/‘)[-1]
40
41     # 固定写法,aiohttp.ClientSession(),实例化一个异步请求对象
42     async with  aiohttp.ClientSession() as aio:
43         # 用该对象向url发送异步请求
44         async with await aio.get(url=url, headers=headers) as ret:
45             # 将响应对象(图片)读取为二进制流,以便存储。(.text().json().read())对应requests的(.text.json.content)
46             res = await ret.read()
47
48     return name, res
49
50
51 # 定义一个回调函数(名字随意),回调函数接收该任务对象本身,(像self)
52 def callback(task):
53     # task.result()接收协程(特殊函数执行的返回结果,可进一步处理)
54     name, res = task.result()
55     # 将二进制流持久化成本地文件
56     with open(os.path.join(‘qiutu‘, name), ‘wb‘) as f:
57         f.write(res)
58     print(name, ‘下载完成‘)
59
60
61 # 通过糗图百科通用页面url,生成十页数据,并将十页数据中的所有图片链接存到urls中
62 urls = []
63 url_ = ‘https://www.qiushibaike.com/pic/page/{}/‘
64 for i in range(1, 10):
65     page_url = url_.format(i)
66     ret = requests.get(url=page_url, headers=headers).text
67     # 通过xpath定位并获取糗图图片的src
68     tree = etree.HTML(ret)
69     url_list = tree.xpath(‘//div[@id="content-left"]/div/div/a/img/@src‘)
70     # 将每个图片的url存到urls中
71     for img_url in url_list:
72         urls.append(img_url)
73         print(img_url)
74
75 tasks = []
76
77 for url in urls:
78     url = ‘https:‘ + url
79     # 执行协程对象函数(函数并不会真正去执行,而是生成一个协程对象)
80     cor = get_img(url)
81     # 将协程对象添加到asyncio.ensure_future中,生成一个任务对象
82     task = asyncio.ensure_future(cor)
83     # 为任务对象绑定添加一个回调函数,传入函数名
84     task.add_done_callback(callback)
85     # 将所有的任务对象添加到任务列表中
86     tasks.append(task)
87
88 # 创建一个事件循环对象
89 loop = asyncio.get_event_loop()
90 # 将任务列表加入事件循环,并开始执行
91 loop.run_until_complete(asyncio.wait(tasks))

注意!:

  一个线程内最多大概可以注册500个协程。。任务数过多,需要多线程加异步协程实现。

原文地址:https://www.cnblogs.com/NoteBook3013/p/11109992.html

时间: 2024-10-07 12:44:23

多任务异步协程,asyncio及aiohttp的相关文章

爬虫第四章 单线程+多任务异步协程

单线程+多任务异步协程: asyncio 事件循环 loop: 无限循环的对象,事件循环中最终需要将一些特殊的函数注册到该事件循环中 特殊的函数: 被ansyc关键字修饰的函数 协程: 本质上是一个对象,可以把协程对象注册到事件循环中, 任务对象:就是对协程对象进一步的封装. 绑定回调函数(即在执行完特殊函数之后执行这个回调函数):task.add_done_callback(func) - func(task) :task 参数表示的就是绑定的任务对象 - task.result() 返回的就

python爬虫--多任务异步协程, 快点,在快点......

多任务异步协程asyncio 特殊函数: - 就是async关键字修饰的一个函数的定义 - 特殊之处: - 特殊函数被调用后会返回一个协程对象 - 特殊函数调用后内部的程序语句没有被立即执行 - 协程 - 对象.协程==特殊的函数.协程表示的就是一组特定的操作. - 任务对象 - 高级的协程(对协程的进一步的封装) - 任务对象==协程==特殊的函数 - 任务对象==特殊的函数 - 绑定回调: - task.add_done_callback(task) - 参数task:当前回调函数对应的任务

单线程实现了多任务异步协程

单线程+多任务异步协程: 意义:提升爬取数据的效率,我们也可以使用线程池, 异步爬虫方式: 多线程/多进程(电脑吃不消,没办法无节制开启)不建议 池:池中的线程或进程也是无法任意开启. 单线程+多任务异步协程(推荐)(500个协程,最优) 概念: 协程:本质就是一个对象,协程对象,怎么去获取?可以使用asynic该关键字去修饰一个函数定义,此时的函数就叫它特殊函数,当该特殊函数被调用之后,就可以返回一个协程对象,特殊之处不仅仅是返回一个协程对象,当函数内部实现的语句不会被立即执行(时间循环开启后

单线程多任务异步协程

目录  1. 概念讲解 2. 多任务异步协程理解 3.基于aiohttp模块异步网络请求实现数据爬取及数据解析 一.需要了解的概念 特殊函数:如果async修饰了一个函数的定义,那么该函数就变成了一个特殊函数, 特殊之处:特殊函数被调用后函数内部实现语句不会被立即执行 该函数调用之后会返回一个协程对象 协程对象:特殊函数调用后可以返回一个协程对象 协程 == 特殊函数 任务对象:对协程对象的进一步封装,就是一个高级协程对象 任务对象 == 协程对象 == 特殊的函数 绑定回调:task.add_

单线程+异步协程

event_loop:事件循环,相当于一个无限循环(不清楚循环多少次),我们可以把一些特殊函数注册(放置)到这个事件循环上,当满足某些条件的时候,函数就会被循环执行.程序是按照设定的顺序从头执行到尾,运行的次数也是完全按照设定.当在编写异步程序时,必然其中有部分程序的运行耗时是比较久的,需要先让出当前程序的控制权,让其在背后(挂起)运行,让另一部分的程序先运行起来.当背后运行的程序完成后,也需要及时通知主程序已经完成任务可以进行下一步操作,但这个过程所需的时间是不确定的,需要主程序不断的监听状态

爬虫 + 数据分析 - 4 异步协程, selenium使用, 自动登录

一.单线程+异步协程 1.基本概念: event_loop:事件循环,相当于一个无限循环,我们可以把一些特殊函数注册(放置)到这个事件循环上, 当满足某些条件的时候,函数就会被循环执行.程序是按照设定的顺序从头执行到尾,运行的次数也是完全按照设定. 当在编写异步程序时,必然其中有部分程序的运行耗时是比较久的,需要先让出当前程序的控制权,让其在背后运行, 让另一部分的程序先运行起来.当背后运行的程序完成后,也需要及时通知主程序已经完成任务可以进行下一步操作, 但这个过程所需的时间是不确定的,需要主

06爬虫-异步协程

1. 前言(目的就是大大提升爬虫效率) 在执行IO密集型任务的时候,代码常常遇到IO操作而等待.例如我们在爬虫的时候,用到requests请求的时候,网页响应慢,一直等待着,那么爬虫的效率会大大的降低. 为了解决这类问题,本文就来探讨一下 Python 中异步协程来加速的方法,此种方法对于 IO 密集型任务非常有效.如将其应用到网络爬虫中,爬取效率甚至可以成百倍地提升. 注:本文协程使用 async/await 来实现,需要 Python 3.5 及以上版本. 2. 基本了解 在了解异步协程之前

爬虫 异步协程

# 基本使用 # 异步轮询的执行 import asyncio async def hello(name): print('hello to:',name) c = hello('zc')#调用 返回协程对象<coroutine协程 object hello at 0x0000000005EDDE08> # 创建一个事件循环对象 loop = asyncio.get_event_loop() # 将协程对象注册到事件循环中,然后启动事件循环对象 loop.run_until_complete(

爬虫速度太慢?来试试用异步协程提速吧!

1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后导致其爬取效率是非常非常低的. 为了解决这类问题,本文就来探讨一下 Python 中异步协程来加速的方法,此种方法对于 IO 密集型任务非常有效.如将其应用到网络爬虫中,爬取效率甚至可以成百倍地提升. 注:本文协程使用 async/await 来实现,需要 Python 3.5 及以上版本. 2.