zoukankan      html  css  js  c++  java
  • 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())
  • 相关阅读:
    Android studio初次安装启动时弹出unable to access android sdk add-on list提示的解决方法
    SQL Server(MSSQLSERVER) 请求失败或服务未及时响应,有关详细信息,请参见事件日志或其他的适用的错误日志。
    Docker启动时提示Get Permission Denied while trying to connect解决方法
    Docker版本与centos和ubuntu环境下docker安装介绍
    菜鸟宝典之Windows Server 2012 R2上PHP、MySQL环境搭建
    Java入门指南-04 顺序、分支、循环
    Java入门指南-03 操作符与表达式
    Java入门指南-02 变量
    Java入门指南-01 基本概要说明
    JavaWeb零基础入门-02 开发环境安装
  • 原文地址:https://www.cnblogs.com/py-peng/p/13188570.html
Copyright © 2011-2022 走看看