####
安装与使用
安装与使用 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库的基础使用,关于更多高级用法建议拜读参考文章中的文章。
####
####