• python协程爬虫-aiohttp+aiomultiprocess使用


    最近使用协程写了个爬虫,效果杠杠的啊,使用aiohttp替代requests发起请求,requests是同步的,会阻塞比较久,再加上aiomultiprocess,实现多进程异步协程,每个进程都单独的事件循环执行多个协程任务;这篇文章主要是记录下这两个库的使用

    aiohttp

    aiohttp是基于asyncio的一个异步http客户端和服务器

    官方文档:https://aiohttp.readthedocs.io/en/stable/client_quickstart.html

    这里我主要记录客户端的操作

    简单实用例子

    async def funct(index):    
        print("start ", index)    
        async with aiohttp.ClientSession() as session:        
            async with session.get("https://movie.douban.com/top250?start=0", timeout=5) as resp:            
                print(resp.status)
                print(await resp.text())    
        print("end ", index)
    

      

    是要先创建一个会话,然后使用这个会话进行请求

    aiohttp.ClientSession()

    创建会话,session提供了各种请求方法,如get、post、delete、put等

    这里认识了新的关键字async with,因为是协程的上下文管理,所以多了async关键字

    这个不是强制使用的,你也可以自己手动关闭会话,但是一定要记得关闭

    注意:

    1、不要为每个请求创建会话。每个应用程序很可能需要一个会话来执行所有请求。

    2、aiohttp在发送请求之前在内部执行URL 规范化。要禁用规范化,请使用encoded=True参数进行URL构建

     

    获取响应信息

    resp.status # 状态码
    await resp.text() # 获取响应正文,可以指定编码
    await resp.read() # 读取二进制响应内容
    await resp.json() # 获取json响应内容
    await resp.content.read(size) # 读取流
    

    注意事项:aiohttp是在await resp.text()之后才发起请求的,所以必须调用之后才能获取响应的内容,不然会出现异常aiohttp.client_exceptions.ClientConnectionError: Connection closed

    aiomultiprocess

    asyncio和多处理本身是有用的,但有局限性:asyncio仍然不能超过GIL的速度,并且多处理一次只能处理一个任务。但是,他们在一起可以充分实现自己的真正潜力。

    aiomultiprocess提供了一个简单的界面,同时在每个子进程上运行完整的asyncio事件循环,从而实现了Python应用程序从未有过的并发级别。每个子进程可以一次执行多个协程,仅受工作量和可用内核数限制。

    注:aiomultiprocess需要Python 3.6或更高版本

    用法

    在子进程中执行协程

    import asyncio
    from aiohttp import request
    from aiomultiprocess import Process
    ​
    async def put(url, params):
        async with request("PUT", url, params=params) as response:
            pass
    ​
    async def main():
        p = Process(target=put, args=("https://jreese.sh", {}))
        await p
    ​
    if __name__ == "__main__":
        asyncio.run(main())
    

      

     

    如果您想从协程中获取结果Worker,请使用以下方法:

    import asyncio
    from aiohttp import request
    from aiomultiprocess import Worker
    ​
    async def get(url):
        async with request("GET", url) as response:
            return await response.text("utf-8")
    ​
    async def main():
        p = Worker(target=get, args=("https://jreese.sh", ))
        response = await p
    ​
    if __name__ == "__main__":
        asyncio.run(main())
    

       

    如果您需要一个托管的工作进程池,请使用Pool

    import asyncio
    from aiohttp import request
    from aiomultiprocess import Pool
    
    async def get(url):
        async with request("GET", url) as response:
            return await response.text("utf-8")
    
    async def main():
        urls = ["https://jreese.sh", ...]
        async with Pool() as pool:
            result = await pool.map(get, urls)
    
    if __name__ == "__main__":
        asyncio.run(main())

     

  • 相关阅读:
    tomcat 闪退处理
    MVC的各个部分都有那些技术来实现?如何实现?
    jsp和servlet的区别、共同点、各自应用的范围?
    如何从CDN加载jQuery?
    window.onload()函数和jQuery中的document.ready()有什么区别?
    JQuery有几种选择器?
    jQuery 库中的 $() 是什么?
    JS 中 == 和 === 区别是什么?
    如何在JavaScript中每x秒调用一个函数
    undefined,null 和 undeclared 有什么区别?
  • 原文地址:https://www.cnblogs.com/alummox/p/12364498.html
Copyright © 2020-2023  润新知