异步进程主要是又三点构成:特殊函数所谓的特殊函数就是被async关键字所修饰的函数,这个函数的返回值由回调函数拿到,协成创建指定的协成对象,实例化任务对象
- 被async关键字修饰的函数定义,该函数就是一个特殊的函数
- 特殊之处:
- 特殊函数被调用后,函数定义的内部实现语句没有被立即执行
- 该函数会返回一个协程对象
- 特殊函数 == 一组指定形式的操作 == 协程对象
- 协程对象 == 一组指定形式的操作
- 创建方式:通过特殊函数调用返回
- 协程对象 == 一组指定形式的操作
- 任务对象就是一个高级的协程对象
- 任务对象 == 协程对象 == 一组指定形式的操作
- 任务对象 == 一组指定形式的操作
- ```
asyncio.ensure_future(c)#这个参数c是实例化的协成对象
```
#定义回调函数
def parse(t):#必须且只能有一个参数(回调函数的调用者表示的那一个任务对象)
result = t.result() #result()返回的就是参数t表示的任务对象对应的特殊函数中的返回值
print(result)
task.add_done_callback(parse) #给任务对象绑定回调函数
- 作用:充当一个容器,用来装在任务对象。当事件循环启动后,就可以异步的执行其内部装载的一个或多个任务对象。
- 创建:loop = asyncio.get_event_loop()
- 启动加载:loop.run_until_complete(task)
import asyncio
import time
#特殊函数的定义
async def get_request(url):
print(‘正在请求url:‘,url)
time.sleep(2)
print(‘请求结束:‘,url)
return 123
#定义回调函数
def parse(t):#必须且只能有一个参数(回调函数的调用者表示的那一个任务对象)
result = t.result() #result()返回的就是参数t表示的任务对象对应的特殊函数中的返回值
print(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) #将一个任务对象装载在loop对象中,切启动了时间循环对象
import asyncio
import time
start = time.time()
urls = [
‘www.1.com‘,
‘www.2.com‘,
‘www.3.com‘
]
#特殊函数的定义
async def get_request(url):
print(‘正在请求url:‘,url)
await asyncio.sleep(2)
print(‘请求结束:‘,url)
return 123
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))
print(‘总耗时:‘,time.time()-start)
from flask import Flask,render_template
from time import sleep
app = Flask(__name__)
@app.route(‘/bobo‘)
def index1():
sleep(2)
return render_template(‘test.html‘)
@app.route(‘/jay‘)
def index2():
sleep(2)
return render_template(‘test.html‘)
@app.route(‘/tom‘)
def index3():
sleep(2)
return render_template(‘test.html‘)
if __name__ == ‘__main__‘:
app.run(debug=True)
爬虫端的代码:
import asyncio
import requests
import time
from lxml import etree
start = time.time()
urls = [‘http://127.0.0.1:5000/bobo‘,
‘http://127.0.0.1:5000/jay‘,
‘http://127.0.0.1:5000/tom‘,]
async def get_request(url):
response = requests.get(url)
page_text = response.text
return page_text
def parse(task):
page_text = task.result()
tree = etree.HTML(page_text)
data = tree.xpath(‘//body/text()‘)[0]
print(data)
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)
#####上述没有实现异步效果,原因在于requests模块不支持异步。
#####使用aiohttp来代替requests
#####aiohttp:
pip install aiohttp
###编码流程:编写大致架构
```python
async def get_request(url):
with aiohttp.ClientSession() as sess:#创建了一个请求对象
with sess.get(url) as response: #发起请求,返回响应对象
page_text = response.text() #read()返回byte类型
return page_text
补充细节
async def get_request(url):
async with aiohttp.ClientSession() as sess:#创建了一个请求对象
async with await sess.get(url) as response: #发起请求,返回响应对象
page_text = await response.text() #read()返回byte类型
return page_text
完整操作
import asyncio
import aiohttp
import time
from lxml import etree
start = time.time()
urls = [‘http://127.0.0.1:5000/bobo‘,
‘http://127.0.0.1:5000/jay‘,
‘http://127.0.0.1:5000/tom‘,]
async def get_request(url):
async with aiohttp.ClientSession() as sess:#创建了一个请求对象
async with await sess.get(url) as response: #发起请求,返回响应对象
page_text = await response.text() #read()返回byte类型
return page_text
def parse(task):
page_text = task.result()
tree = etree.HTML(page_text)
data = tree.xpath(‘//body/text()‘)[0]
print(data)
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/niuyeji648/p/15154326.html