异步网络模块之aiohttp的使用(一)
异步网络模块之aiohttp的使用(一)
平时我们也许用的更多的是requests模块,或者是requests_hml模块,但是他们都属于阻塞类型的不支持异步,速度很难提高,于是后来出现了异步的grequests,开始了异步网络请求,速度得到了大大的提升,但是今天我们要说的另外的一个比较异步网络请求模块-aiohttp。
什么是aiohhtp?
要学习一个模块,首先要知道这个模块都能做什么,我们从官网上找到了关于aiohttp的解释。
Asynchronous HTTP Client/Server for asyncio and Python.
Supports both Client and HTTP Server.
Supports both Server WebSockets and Client WebSockets out-of-the-box without the Callback Hell.
Web-server has Middlewares, Signals and pluggable routing.
大概意思是说aiohttp是一个异步http网络模块分为了客户端和服务端,同时支持websocket的使用,另外不用担心在使用过程中多次回调导致回调地狱情况出现。
如何安装?
在linux直接pip安装应该没什么问题,一般都坑在windows系统上,我使用win10 64位系统直接安装也是没有出现什么问题,
官网上推荐的是先按照cchardet,这是一个关于网页编码的模块直接运行下面命令即可
pip install cchardet
之后我们安装
pip install aiohttp
后面的操作我们需要还要安装一个协程模块asyncio。
pip install asyncio
ok,没什么问题安装我们就到这里了。
如何使用
我们先看一段代码,后面会对代码作出解释。
import asyncio #导入协程包
import aiohttp #导入aiohttp
from lxml import html #导入html解析模块
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"}
async def getsource(url):
conn=aiohttp.TCPConnector(verify_ssl=False)#防止ssl报错
async with aiohttp.ClientSession(connector=conn) as session: #创建session
async with session.get(url,headers=headers,timeout=60) as req: #获得请求
if req.status==200: #判断请求码
source=await req.text()#使用await关键字获取返回结果
print(html.fromstring(source).xpath("//title/text()")[0]) #获取网页标题
else:
print("访问失败")
if __name__=="__main__":
full_urllist=
["https://www.baidu.com","https://www.cnblogs.com","https://www.jianshu.com"]
event_loop = asyncio.get_event_loop() #创建事件循环
tasks = [getsource(url) for url in full_urllist]
results = event_loop.run_until_complete(asyncio.wait(tasks))#等待任务结束
-----------------------------------------运行结果---------------------------------------------
部分内容已经在上面的代码中标注了,下面我们开始对上面的内容进行分析。
async/await
首先我们需要知道关键字async/await,在方法的面前加关键字async之后该方法就成了一个协程了,
一般await关键字使用的使用所在的方法必须带有async,关于两个关键字的演变,要从yield说起,
演变过程请参考http://python.jobbole.com/86069/,这里只要知道是协程意思就行了。
首先我定义了连接器并取消ssl安全验证,我们使用verify_ssl使其等于False,默认是True的。
TCPConnector
因为有的网站请求的时候会验证ssl证书,如果是自签名的ssl证书会出错。
conn=aiohttp.TCPConnector(verify_ssl=False)#防止ssl报错
下面是关于TCPConnector的所有参数部分。
class aiohttp.TCPConnector(*, ssl=None, verify_ssl=True, fingerprint=None, use_dns_cache=True, ttl_dns_cache=10, family=0, ssl_context=None, local_addr=None, resolver=None, keepalive_timeout=sentinel, force_close=False, limit=100, limit_per_host=0, enable_cleanup_closed=False, loop=None)
limit
为了限制同时打开的连接数量,我们可以将限制参数传递给连接器:
conn = aiohttp.TCPConnector(limit=30)#同时最大进行连接的连接数为30,默认是100,limit=0的时候是无限制
limit_per_host:
conn = aiohttp.TCPConnector(limit_per_host=30)#默认是0
同一端点的最大连接数量。同一端点即(host, port, is_ssl)完全相同.
ClientSession
首先我们创建一个session对象,向下面这样使用async声明异步,同时with上下文关键字 省去了关闭连接的代码,
async with aiohttp.ClientSession(connector=conn) as session:
下面是ClientSession的所有参数,这里用的比较多的是connector,headers,cookies其他的参数大家可以去自己探索一下。
class aiohttp.ClientSession(*, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, json_serialize=json.dumps, version=aiohttp.HttpVersion11, cookie_jar=None, read_timeout=None, conn_timeout=None, timeout=sentinel, raise_for_status=False, connector_owner=True, auto_decompress=True, proxies=None
session.get
上面我们创建了session对象,然后我们就要进行请求具体的网站了。
async with session.get(url,headers=headers,timeout=60) as req: #获得请求
这一步我们像使用requests那样传入headers参数并指定最大超时为60s。
ClientResponse
然后我们判断请求是否情况,之后我们使用await req.text()获取了网页的源码,注意这里必须使用await关键字来获取协程的结果。然后我们使用了lxml模块获取这三个网页的title标题。
到目前为止我们只是定义了一个协程,并没有真正的运行它接下来我们看看main方法是做什么的。
full_urllist=
["https://www.baidu.com","https://www.cnblogs.com","https://www.jianshu.com"]
event_loop = asyncio.get_event_loop() #创建时间循环
tasks = [getsource(url) for url in full_urllist]
results = event_loop.run_until_complete(asyncio.wait(tasks))#等待任务结束
首先我定义了一个列表含有三个目标url,当前你可以定义更多。
asyncio.get_event_loop方法可以创建一个事件循环,然后使用run_until_complete将协程注册到事件循环,并启动事件循环。
协程对象不能直接运行,在注册事件循环的时候,其实是run_until_complete方法将协程包装成为了一个任务(task)对象。所谓task对象是Future类的子类。保存了协程运行后的状态,用于未来获取协程的结果。
asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task,run_until_complete的参数是一个futrue对象。当传入一个协程,其内部会自动封装成task,task是Future的子类。isinstance(task, asyncio.Future)将会输出True。
简单的我们就了解到这吧,如果有什么不懂的地方请留言大家一起讨论。
最新文章
- DEDEcms 在php5.4以上 后台登录空白解决办法
- QT error: cannot find -lGL
- TortoiseGit与GitHub项目关联设置
- Windows Directory ACL Security Check By ACL Baseline
- 获取技能的成功经验和关于C语言学习的调查 2015528
- css虚线和css双实线
- 什么是工程师文化?各位工程师是为什么活的?作为一个IT或互联网公司为什么要工程师文化?
- Google机器学习教程心得(三) 好的feature
- MIPS平台目标机安装Oprofile时出现error
- C#之自己定义的implicit和explicit转换
- ubuntu 12.04 x86_64:java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons
- 2018-2019-2-20175235 实验一 《Java开发环境的熟悉》实验报告
- P5303 [GXOI/GZOI2019]逼死强迫症
- ssh 免密码登录(设置后仍需输密码的原因及解决方法)
- contains用法
- Pipenv和Python虚拟环境
- 又一国产855旗舰突然现身:支持5G
- 多重背包!!!(二进制优化的01背包)hdoj-2844
- Java的HashMap
- YII关联查询
热门文章
- html的body内标签之input系列2
- 【刷题】BZOJ 3510 首都
- [BZOJ5292] [BJOI2018]治疗之雨
- bzoj 1877: [SDOI2009]晨跑 (网络流)
- BZOJ3238:[AHOI2013]差异——题解
- UVA.548 Tree(二叉树 DFS)
- bzoj2083: [Poi2010]Intelligence test(二分+vector)
- 【图论-最短路】【P3393】逃离僵尸岛
- requireJs使用方法项目实例
- OLTP与OLAP比较【转】