6.1 gevent模块
-
gevent模块属于第三方模块
from gevent import monkey;monkey.patch_all() import gevent import time def eat(name): print('%s eat 1' %name) gevent.sleep(2) # gevent可以识别的io阻塞 print('%s eat 2' %name) def play(name): print('%s play 1' %name) time.sleep(1) # gevent不能直接识别,需要首行打补丁 print('%s play 2' %name) g1=gevent.spawn(eat,'egon') g2=gevent.spawn(play,name='egon') # 或者gevent.joinall([g1,g2]) g1.join() g2.join() print('主')
6.2 asyncio模块
-
asyncio模块是python内置的模块
import asyncio """ 直接调用 """ # 用async定义一个协程 async def request(url): print('正在请求的url是', url) print('请求成功,', url) return url # 被async修饰的函数,调用之后返回一个 协程对象c c = request('www.baidu.com') # 1. 基于asyncio 创建一个 事件循环对象loop loop = asyncio.get_event_loop() # 2. 将 协程对象c 注册到 事件循环对象loop 中,然后启动loop loop.run_until_complete(c)
import asyncio """ 通过task对象调用 """ # 用async定义一个协程 async def request(url): print('正在请求的url是', url) print('请求成功,', url) return url # 被async修饰的函数,调用之后返回一个协程对象c c = request('www.baidu.com') # 1. 基于asyncio 创建一个 事件循环对象loop loop = asyncio.get_event_loop() # 2. 基于loop 创建一个 task对象 task = loop.create_task(c) # 3. 将 task对象 注册到 事件循环对象loop 中,然后启动loop print(task) loop.run_until_complete(task) print(task)
import asyncio """ 通过future对象调用 """ # 用async定义一个协程 async def request(url): print('正在请求的url是', url) print('请求成功,', url) return url # 被async修饰的函数,调用之后返回一个协程对象c c = request('www.baidu.com') # 1. 基于asyncio 创建一个 事件循环对象loop loop = asyncio.get_event_loop() # 2. 基于asyncio 创建一个 future对象 future = asyncio.ensure_future(c) # 3. 将 future对象 注册到 事件循环对象loop 中,然后启动loop print(future) loop.run_until_complete(future) print(future)
import asyncio """ 调用回调函数 """ # 用async定义一个协程 async def request(url): print('正在请求的url是', url) print('请求成功,', url) return url def callback_func(future): # result()返回的是任务对象中封装的协程对象对应函数的返回值 print(future.result()) # 被async修饰的函数,调用之后返回一个 协程对象c c = request('www.baidu.com') # 1. 基于asyncio 创建一个 事件循环对象loop loop = asyncio.get_event_loop() # 2. 基于asyncio 创建一个 future对象 future = asyncio.ensure_future(c) # 3. 将 回调函数 绑定到 future对象 中 future.add_done_callback(callback_func) # 4. 将 future对象 注册到 事件循环对象loop 中,然后启动loop loop.run_until_complete(future)
-
示例一:模拟
import asyncio # 用async定义一个协程 async def request(url): print('正在下载', url) # 异步协程中出现同步模块相关的代码,无法实现异步。 # time.sleep(2) # 在asyncio中遇到阻塞操作,用await进行手动挂起 await asyncio.sleep(2) print('下载完毕', url) urls = [ 'www.baidu.com', 'www.sogou.com', 'www.goubanjia.com' ] # 任务列表:存放多个任务对象 tasks = [] for url in urls: c = request(url) task = asyncio.ensure_future(c) tasks.append(task) loop = asyncio.get_event_loop() # 将任务列表封装到wait中 loop.run_until_complete(asyncio.wait(tasks))
-
示例二:访问flask服务器
import requests import asyncio import aiohttp async def get_page(url): async with aiohttp.ClientSession() as session: # get()、post(): # headers,params/data,proxy='http://ip:port' async with await session.get(url=url) as response: # text()返回字符串形式的响应数据 # read()返回的二进制形式的响应数据 # json()返回的就是json对象 # 注意:获取响应数据前,要用await进行手动挂起 page_text = await response.text() print(page_text) urls = [ 'www.baidu.com', 'www.sogou.com', 'www.goubanjia.com' ] # 任务列表:存放多个任务对象 tasks = [] for url in urls: c = get_page(url) task = asyncio.ensure_future(c) tasks.append(task) loop = asyncio.get_event_loop() # 将任务列表封装到wait中 loop.run_until_complete(asyncio.wait(tasks))
-
示例三:访问网页
import asyncio import aiohttp class GetArticle(object): def __init__(self, url, file): pass async def article2dict(self, menu_dict): pass # 异步协程:请求文章URL的text内容 async with aiohttp.ClientSession() as session: try: async with await session.get(url=article_url, headers=self.headers, timeout=5) as response: # 使用gbk进行解码 article_text = await response.text(encoding='gbk') except Exception: for i in range(1, 10): print(f'请求 {article_url} 超时,第{i}次重复请求') async with await session.get(url=article_url, headers=self.headers, timeout=5) as response: article_text = await response.text(encoding='gbk') print(f'第{i}次重复请求 {article_url} 成功') # 访问成功,跳出循环 break pass def run(self): """ 主函数 :return: """ pass # 任务列表:存放多个任务对象 tasks = [] for menu_dict in menu_list: c = self.article2dict(menu_dict) task = asyncio.ensure_future(c) tasks.append(task) loop = asyncio.get_event_loop() # 将任务列表封装到wait中 loop.run_until_complete(asyncio.wait(tasks)) pass