协程的 async/await 实现

import asyncio

async def request(url):
    print('开始请求', url)
    print('结束请求', url)
    return url + ' |--over'

def callback_func(task):
    # task, 回调函数,获取返回值
    print(task.result())

url = 'http://www.baidu.com'

# 被 async 修饰的函数,直接调用不会执行,会返回一个协程对象
coroutines_obj = request(url)

# 构建一个事件循环对象,管理所有的事件,在整个程序运行过程中不断循环执行并追踪事件发生的顺序将它们放在队列中,
# 空闲时调用相应的事件处理者来处理这些事件。
# loop = asyncio.get_event_loop()
# # 阻塞调用,直到协程运行结束才返回。参数是future,传入协程对象时内部会自动变为future
# loop.run_until_complete(coroutines_obj)

# 使用 task, 封装协程对象。包含了 任务的各个状态
loop = asyncio.get_event_loop()
task = loop.create_task(coroutines_obj) # 等价于 task = asyncio.ensure_future(coroutines_obj)
# 通过回调函数,获取绑定函数返回值
task.add_done_callback(callback_func)

print(task)
loop.run_until_complete(task)
# 运行完毕后 获取返回值 .result()。没有运行完毕,result()方法不会阻塞去等待结果,而是抛出 asyncio.InvalidStateError 错误
print(task.result())
print(task)

追加:

  • 多个任务的注册使用 loop.create_task(asyncio.wait([coroutines_obj, ])).
  • 注意 在异步协程中出现了同步模块相关的代码,那么就无法实现异步。 time.sleep(2) >> asyncio.sleep(2)
  • 当在 asyncio 中遇到阻塞操作,必须手动挂起 await asyncio.sleep(2)

最新

  • python3.7 支持的新方法, 直接注册,不需要显式构建循环对象.可以在参数导入的函数创建 task 对象
  • asyncio.run(coroutines_obj)
  • 更多

爬虫,单线程+异步协程

使用 async/await 实现

import aiohttp
import requests
import asyncio
import time

start = time.time()

# 简单flask服务器, 每个数据返回耗时两秒
urls = ['http://127.0.0.1:5000' + i for i in ('/', '/a', '/b', '/c')]


async def get_page(url):
    print('开始请求', url)
    # requests.get() 是基于同步的网络请求模块。 在异步协程中出现了同步模块相关的代码,那么就无法实现异步。
    # text = requests.get(url).text # 程序运行耗时 8s
    # aiohttp 基于异步的网络请求模块, 区别 proxies={"http": '123.55.102.9:9999'} ==>  proxy="ip/prot"
    async with aiohttp.ClientSession() as session:
        # 当在 asyncio中遇到阻塞操作,必须手动挂起 await
        async with await session.get(url) as response:
            text = await response.text()
            print(f'{url} 结束--: \n {text}')  # 耗时 2s


tasks = [asyncio.ensure_future(get_page(i)) for i in urls]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print('总耗时:', time.time() - start)
  • aiohttp 基于异步的网络请求模块, async with aiohttp.ClientSession() as session 用法与 requests 相似
  • ip 代理方式改变 proxies={"http": '123.55.102.9:9999'} ==> proxy="ip:port"

相关推荐:

来自系列:Python 爬虫学习笔记

分类 python下文章:

1.0 爬虫的介绍,和requests模块的简单使用

1.1 数据解析的三种方式。正则表达式, bs4, xpath

2.0 多任务(进程,协程,线程)爬虫:验证码识别,返回头储存,ip代理 介绍。 异步是什么,爬虫异步的方式。线程,进程,介绍

3.0 基于selenium 模块的 爬虫操作。 selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

更多...

评论([[comments.sum]])

发表

加载更多([[item.son.length-2]])...

发表

2020-11 By chuan.

Python-flask & bootstrap-flask

图片外链来自:fghrsh

互联网ICP备案号:蜀ICP备2020031846号