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())
  • 相关阅读:
    CF1454F Array Partition
    leetcode1883 准时抵达会议现场的最小跳过休息次数
    leetcode1871 跳跃游戏 VII
    leetcode1872 石子游戏VIII
    CF1355C Count Triangles
    CF1245D Shichikuji and Power Grid
    CF1368C Even Picture
    CF1368D AND, OR and square sum
    CF1395C Boboniu and Bit Operations
    SpringBoot和开发热部署
  • 原文地址:https://www.cnblogs.com/py-peng/p/13188570.html
Copyright © 2011-2022 走看看