Python asyncio
asyncio
快速使用
import asyncio async def request(url): print("request正在执行 %s"%url) print("request执行完成 %s"%url) # 创建实践循环 event_loop = asyncio.get_event_loop() # 启动 event_loop.run_until_complete(request("www.baidu.com"))
task与future
本质没差别,只是调用的方法不同。
task基于事件循环来创建
future基于asyncio来创建
import asyncio async def request(url): print("request正在执行 %s"%url) print("request执行完成 %s"%url) # 创建实践循环 event_loop = asyncio.get_event_loop() # 创建future与task对象 future = asyncio.ensure_future(request("www.baidu.com")) task = event_loop.create_task(request("www.google.com")) # 启动 event_loop.run_until_complete(future) event_loop.run_until_complete(task)
回调函数
import asyncio async def request(url): print("request正在执行 %s"%url) return "request执行完成 %s"%url def callback_func(task): print(task.result()) # result 获取返回值 # 创建实践循环 event_loop = asyncio.get_event_loop() # 创建task对象 task = event_loop.create_task(request("www.badidu.com")) # 绑定回调函数 task.add_done_callback(callback_func) # 启动 event_loop.run_until_complete(task)
多任务操作
上面的实例,都是单任务操作。
import asyncio import time async def request(url): print("request正在执行 %s"%url) await asyncio.sleep(2) return "request执行完成 %s"%url def callback_func(task): print(task.result()) # result 获取返回值 event_loop = asyncio.get_event_loop() # 创建事件循环 urls = ["www.baidu.com","www.douban.com","www.python.com"] tasks = [] for url in urls: task = event_loop.create_task(request(url)) # 创建task task.add_done_callback(callback_func) # 绑定回调函数 tasks.append(task) start_time = time.time() event_loop.run_until_complete(asyncio.wait(tasks)) # 启动 end_time = time.time() - start_time print(end_time)
为什么没用time.time(),
而是await asyncio.sleep()
?
如果出现同步模块相关的代码,那么就无法实现异步。
await asyncio.sleep()
,代码中await
是什么?
当asyncio遇到堵塞操作,需手动挂起,而挂起就需要await
来实现。
使用协程爬去数据
asyncio不能单独完成网络的协程,需要与aiohttp配合才行。
https://www.cnblogs.com/py-peng/p/12256019.html
import asyncio import aiohttp from fake_useragent import UserAgent async def get_source(url): ua = UserAgent().random # 获取随机ua headers = {"User-Agent":ua} async with aiohttp.ClientSession() as session: # 创建session async with session.get(url,headers=headers,verify_ssl=False) as response: # 发送请求 text = await response.read() # 读取二进制数据,text()是文本,前面需要加await print("Text Count: %s"%len(text)) urls = ["http://baidu.com","http://douban.com","http://qq.com/"] tasks = [] event_loop = asyncio.get_event_loop() for url in urls: task = event_loop.create_task(get_source(url)) # 创建task tasks.append(task) event_loop.run_until_complete(asyncio.wait(tasks)) # 启动
gevent
快速使用
import gevent def get_source(url): print("正在请求 %s"%url) gevent.sleep(2) return "执行完成 %s"%url g = gevent.spawn(get_source,"www.baidu.com") # 生成对象 result = g.get() # 获取函数返回值 print(result)
多任务操作
import gevent def get_source(url): print("正在请求 %s"%url) gevent.sleep(2) return "执行完成 %s"%url def get_event(url,spawn_func): return gevent.spawn(spawn_func, url) urls = ["http://www.baidu.com","http://www.douban.com","http://www.python.org"] response = gevent.joinall([get_event(url,get_source) for url in urls]) # 生产事件对象 for rep in response: print(rep.get()) # 获取结果
使用协程爬去数据
必须导入gevent文件夹下的monkey,还需要使用monkey这个函数。
from gevent import monkey # 导入monkey monkey.patch_all() # 使用该函数 import gevent import requests def get_source(url): response = requests.get(url) return "Source: %s --- Status: %s"%(url, response.status_code) def get_event(url,spawn_func): return gevent.spawn(spawn_func, url) urls = ["http://www.baidu.com","http://www.douban.com","http://www.python.org"] response = gevent.joinall([get_event(url,get_source) for url in urls]) # 生产协程对象 for rep in response: print(rep.get())