单线程多任务异步协程
时间:2019-10-22
本文章向大家介绍单线程多任务异步协程,主要包括单线程多任务异步协程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
目录
1. 概念讲解
2. 多任务异步协程理解
3.基于aiohttp模块异步网络请求实现数据爬取及数据解析
一、需要了解的概念
特殊函数:如果async修饰了一个函数的定义,那么该函数就变成了一个特殊函数,
特殊之处:特殊函数被调用后函数内部实现语句不会被立即执行
该函数调用之后会返回一个协程对象
协程对象:特殊函数调用后可以返回一个协程对象
协程 == 特殊函数
任务对象:对协程对象的进一步封装,就是一个高级协程对象
任务对象 == 协程对象 == 特殊的函数
绑定回调:task.add_done_callback(parse) #parse就是一个回调函数
parse的定义:
parse必须又一个参数,该参数表示的就是回调函数对应的任务对象
task.result(): 就是特殊函数的的返回值
事件循环对象:可以让特殊函数内部的语句执行
该对象内部必须注册的是任务对象,当事件循环开启后其内部注册的任务对象就可以基于异步被执行
ps: 在特殊函数每部不可以出现不支持异步代码对应的模块
定义如下:
import asyncio import time urls = [ 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', ] # 特殊函数 async def get_request(url): print('正在请求:',url) time.sleep(2) print('请求结束;',url) return 'bobo' #对调函数 def parse(task): #task 该回调函数对应的任务对象 print(' I am callback') print(task.result()) #result返回的就是特殊函数的返回值 #返回了一个协程对象 c = get_request('www.1.com') #任务对象 task = asyncio.ensure_future(c) #给任务对象绑定回调,任务对象执行完后才能被执行 task.add_done_callback(parse) #创建一个事件循环对象 loop = asyncio.get_event_loop() #需要将任务对象注册到事件循环对象中且需要启动循环对象 loop.run_until_complete(task)
二、多任务异步协程过程理解
import asyncio import time urls = [ 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', ] start = time.time() # 特殊函数 #!!!特殊函数内部不可以出现不支持异步的模块代码,如果出现了则会中断所有的异步代码 async def get_request(url): print('正在请求:',url) #time.sleep(2) await asyncio.sleep(2) #await 遇到阻塞的时候需要阻塞然后再走后续代码 print('请求结束;',url) return 'bobo' #任务列表 tasks = [] for url in urls: c = get_request(url) #执行特殊函数得到一个协程对象 task = asyncio.ensure_future(c) #获取任务对象 tasks.append(task) #一个任务对象和另一个任务对象所对应的代码是异步的 #某一个对象内部的代码是串行的
# 注册的任务对象 事件循环开启 loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) #此处的wait当任务对象遇到阻塞的时候允许挂起,把cpu的使用权交出来 print('耗时',time.time()-start)
三、基于aiohttp模块异步网络请求实现数据爬取及数据解析
1. aiphttp模块使用详解
pip install aiohttp 编码: 基本架构: with aiohttp.ClientSession() as s: #s就是一个请求对象 with s.get(url) as response: page_text = response.text() #read() ==> content json没变 return page_text 补充细节 在每个with前加async 在每个阻塞前加await async with aiohttp.ClientSession() as s: #s就是一个请求对象 async with await s.get(url) as response: page_text = await response.text() #read() ==> content json没变 return page_text
2.aioihttp使用案列及说明及数据解析
import asyncio import time import requests import aiohttp from lxml import etree urls = [ 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom', ] start = time.time() # 特殊函数 #!!!特殊函数内部不可以出现不支持异步的模块代码,如果出现了则会中断所有的异步代码 async def get_request(url): #requests模块是不支持异步的 # page_text = requests.get(url).text # return page_text async with aiohttp.ClientSession() as s: #s就是一个请求对象 async with await s.get(url) as response: #get/post(url,data/parms,headers,proxy='http://ip:port') page_text = await response.text() #read() ==> content json没变 return page_text #定义回调函数 def parse(task): page_text = task.result() tree = etree.HTML(page_text) print(tree.xpath('//a/text()')) #任务列表 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(asyncio.wait(tasks)) print('耗时',time.time()-start)
原文地址:https://www.cnblogs.com/guniang/p/11718937.html
- webpack学习(五)配置详解
- 1131: [POI2008]Sta
- 3172: [Tjoi2013]单词
- WebApiThrottle限流框架使用手册
- webpack学习(六)打包压缩js和css
- 1051: [HAOI2006]受欢迎的牛
- 1572: [Usaco2009 Open]工作安排Job
- 深海中的STL—mt19937
- 探索ASP.NET MVC5系列之~~~4.模型篇---包含模型常用特性和过度提交防御
- POJ1201 Intervals(差分约束)
- 【NLP】十分钟快览自然语言处理学习总结
- MVC5 网站开发之九 网站设置
- Redis安全小结
- webpack学习(七)打包压缩图片
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法