• 8-3-2python语法基础-并发编程-协程-aiohttp的使用


    #### 

     安装与使用

    安装与使用
    install
    pip install aiohttp 
    简单实例使用
    aiohttp的自我介绍中就包含了客户端和服务器端,所以我们分别来看下客户端和服务器端的简单实例代码。
    
    客户端:
    import aiohttp
    import asyncio
    
    async def fetch(session, url):
        async with session.get(url) as response:
            return await response.text()
    
    
    async def main():
        async with aiohttp.ClientSession() as session:
            html = await fetch(session, "http://httpbin.org/headers")
            print(html)
    
    asyncio.run(main())
    
    
    """输出结果:
    {
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "Python/3.7 aiohttp/3.6.2"
      }
    }
    """
    这个代码是不是很简单,一个函数用来发起请求,另外一个函数用来下载网页。
    
    服务器端
    from aiohttp import web
    
    
    async def handle(request):
        name = request.match_info.get('name', "Anonymous")
        text = "Hello, " + name
        return web.Response(text=text)
    
    app = web.Application()
    app.add_routes([web.get('/', handle),
                    web.get('/{name}', handle)])
    
    if __name__ == '__main__':
        web.run_app(app)
    运行这个代码,然后访问http://127.0.0.1:8080就可以看到你的网站了,很 基础的一个网页,你可以在后面跟上你的名字。
    
    这是两个简单的关于aiohttp的使用示例,下面快速开始。

    ####

    入门简单示范

    入门简单示范
    首先是学习客户端,也就是用来发送http请求的用法。首先看一段代码,会在代码中讲述需要注意的地方:
    
    import aiohttp
    import asyncio
    
    async def main():
        async with aiohttp.ClientSession() as session:
            async with session.get('http://httpbin.org/get') as resp:
                print(resp.status)
                print(await resp.text())
    
    asyncio.run(main())
    

    ####

    代码解释

    在网络请求中,一个请求就是一个会话,然后aiohttp使用的是ClientSession来管理会话,所以第一个重点,看一下ClientSession类:
    
    在源码中,这个类的注释是使用HTTP请求接口的第一个类。然后上面的代码就是实例化一个ClientSession类然后命名为session,然后用session去发送请求。
    
    async with aiohttp.ClientSession() as session:
    
    注意如果是请求的https的,还可能遇到证书的问题,可以使用:
    async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=64,verify_ssl=False)) as session:
    
    下面讲解get的使用:
    async with session.get('http://httpbin.org/get') as resp:
    
    时候在发起网络请求的时候需要附加一些参数到url中,这一点也是支持的。
    
    params = {'key1': 'value1', 'key2': 'value2'}
    async with session.get('http://httpbin.org/get',
                           params=params) as resp:
        expect = 'http://httpbin.org/get?key2=value2&key1=value1'
        assert str(resp.url) == expect
    
    
    读取响应内容
    读取到服务器的响应状态和响应内容,这个很重要
    用法:
    async def main():
        async with aiohttp.ClientSession() as session:
            async with session.get('http://httpbin.org/get') as resp:
                print(resp.status)
                print(await resp.text(encoding=utf-8))
    
    
    非文本内容格式
    对于网络请求,有时候是去访问一张图片,这种返回值是二进制的也是可以读取到的:
    await resp.read()
    将text()方法换成read()方法就好。

    #####

    请求的自定义:

    请求的自定义
    自定义Headers
    有时候做请求的时候需要自定义headers,主要是为了让服务器认为我们是一个浏览器。然后就需要我们自己来定义一个headers:
    
    headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko)"
                          " Chrome/78.0.3904.108 Safari/537.36"
        }
    await session.post(url, headers=headers)
    
    
    自定义cookie
    发送你自己的cookies给服务器,你可以为ClientSession对象指定cookies参数:
    url = 'http://httpbin.org/cookies'
    cookies = {'cookies_are': 'working'}
    async with ClientSession(cookies=cookies) as session:
        async with session.get(url) as resp:
            assert await resp.json() == {
               "cookies": {"cookies_are": "working"}}
    
    
    
    使用代理
    有时候在写爬虫的时候需要使用到代理,所以aiohttp也是支持使用代理的,我们可以在发起请求的时候使用代理,只需要使用关键字proxy来指明就好,
    但是有一个很难受的地方就是它只支持http代理,不支持HTTPS代理。使用起来大概是这样: proxy
    = “http://127.0.0.1:10809” async with aiohttp.ClientSession(headers=headers) as session: async with session.get(url=login_url, proxy=proxy) as response: resu = await response.text()

    #####

    和asyncio结合使用

    和asyncio结合使用
    其实aiohttp最适合的伴侣就是asyncio,这两个结合起来使用是最好不过的了。然后这里我就写一个简单的实例代码来对比一下。同步和异步的差别。
    
    示例代码
    示例就简单的用豆瓣电影吧,这是我从开始学习爬虫就一直练习的网站。然后写一些基本需要使用到的库:
    
    lxml
    requests
    datetime
    asyncio
    aiohttp
    然后需要大家安装好这些库,然后提取网页内容使用的是xpath。
    
    同步
    其实同步写了很多次了,然后把之前的代码放上来就好:
    
    from datetime import datetime
    
    import requests
    from lxml import etree
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit"
                             "/537.36 (KHTML, like Gecko) "
                             "Chrome/72.0.3626.121 Safari/537.36"}
    
    
    def get_movie_url():
        req_url = "https://movie.douban.com/chart"
        response = requests.get(url=req_url, headers=headers)
        html = etree.HTML(response.text)
        movies_url = html.xpath(
            "//*[@id='content']/div/div[1]/div/div/table/tr/td/a/@href")
        return movies_url
    
    
    def get_movie_content(movie_url):
        response = requests.get(movie_url, headers=headers)
        result = etree.HTML(response.text)
        movie = dict()
        name = result.xpath('//*[@id="content"]/h1/span[1]//text()')
        author = result.xpath('//*[@id="info"]/span[1]/span[2]//text()')
        movie["name"] = name
        movie["author"] = author
        return movie
    
    
    if __name__ == '__main__':
        start = datetime.now()
        movie_url_list = get_movie_url()
        movies = dict()
        for url in movie_url_list:
            movies[url] = get_movie_content(url)
        print(movies)
        print("同步用时为:{}".format(datetime.now() - start))
    
    看一下同步的结果:
    
    E:venvspiderScriptspython.exe E:/python_project/filetest/douban.py
    [{'name': ['小丑 Joker'], 'author': ['托德·菲利普斯']}, {'name': ['好莱坞往事 Once Upon a Time... in Hollywood'], .....
    同步用时为:0:00:08.765342 异步 异步也很简单,关于异步的文章我还在整理,因为涉及到太多的东西了。先看这个爬虫代码: import asyncio from datetime import datetime import aiohttp from lxml import etree headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit" "/537.36 (KHTML, like Gecko) " "Chrome/72.0.3626.121 Safari/537.36"} async def get_movie_url(): req_url = "https://movie.douban.com/chart" async with aiohttp.ClientSession(headers=headers) as session: async with session.get(url=req_url, headers=headers) as response: result = await response.text() result = etree.HTML(result) return result.xpath("//*[@id='content']/div/div[1]/div/div/table/tr/td/a/@href") async def get_movie_content(movie_url): async with aiohttp.ClientSession(headers=headers) as session: async with session.get(url=movie_url, headers=headers) as response: result = await response.text() result = etree.HTML(result) movie = dict() name = result.xpath('//*[@id="content"]/h1/span[1]//text()') author = result.xpath('//*[@id="info"]/span[1]/span[2]//text()') movie["name"] = name movie["author"] = author return movie if __name__ == '__main__': start = datetime.now() loop = asyncio.get_event_loop() movie_url_list = loop.run_until_complete(get_movie_url()) tasks = [get_movie_content(url) for url in movie_url_list] movies = loop.run_until_complete(asyncio.gather(*tasks)) print(movies) print("异步用时为:{}".format(datetime.now() - start)) 看一下结果,你就知道差距了: E:venvspiderScriptspython.exe E:/python_project/filetest/aio_douban.py [{'name': ['小丑 Joker'], 'author': ['托德·菲利普斯']}, {'name': ['好莱坞往事 Once Upon a Time... in Hollywood'], .....
    异步用时为:0:00:02.230956 Process finished with exit code 0 总结 异步是未来,这一点毋庸置疑。写了一点aiohttp库的基础使用,关于更多高级用法建议拜读参考文章中的文章。

    ####

    ####

  • 相关阅读:
    计算机技术与软件专业以考代评政策之我见
    关于设立运营部门的我的几点建议
    自助式微软BI工具PowerPivot简介!
    写在两年前的公司新版CRM系统需求探讨
    实时音视频开发之开源项目
    vue3.0 使用vue脚手架生成vue项目 运行mapbox 3D地图例子
    Vue开发工具Visual Studio Code 配置插件
    sip协议开源实现
    redis操作
    SIP协议 Java开源jar
  • 原文地址:https://www.cnblogs.com/andy0816/p/15045812.html
Copyright © 2020-2023  润新知