异步网络模块之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。

简单的我们就了解到这吧,如果有什么不懂的地方请留言大家一起讨论。

异步网络模块之aiohttp的使用(一)的更多相关文章

  1. python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据

    python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...

  2. 异步网络编程aiohttp的使用

    aiohttp的使用 aiohttp Asynchronous HTTP Client/Server for asyncio and Python. Supports both Client and ...

  3. 爬虫----异步---高性能爬虫----aiohttp 和asycio 的使用

    前情提要: 首先膜拜loco大佬 肯定有人像我一样.不会异步,发一下. 一:性能比对 多进程,多线程,(这里不建议使用,太消耗性能) 进程池和线程池 (可以适当的使用) 单线程+异步协程   (推荐使 ...

  4. 小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  5. python 基于aiohttp的异步爬虫实战

    钢铁知识库,一个学习python爬虫.数据分析的知识库.人生苦短,快用python. 之前我们使用requests库爬取某个站点的时候,每发出一个请求,程序必须等待网站返回响应才能接着运行,而在整个爬 ...

  6. 利用aiohttp制作异步爬虫

      asyncio可以实现单线程并发IO操作,是Python中常用的异步处理模块.关于asyncio模块的介绍,笔者会在后续的文章中加以介绍,本文将会讲述一个基于asyncio实现的HTTP框架--a ...

  7. 异步编程之asyncio简单介绍

    引言: python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率,弥补了python性能方面的短板. as ...

  8. python中的的异步IO

    asyncio 是干什么的? 异步网络操作 并发 协程 python3.0 时代,标准库里的异步网络模块:select(非常底层) python3.0时代,第三方异步网络库:Tornado pytho ...

  9. python下载mp4 同步和异步下载支持断点续下

    Range 用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式: Range:(unit=first byte pos)-[last byte pos] Range 头部的格式有以下几种 ...

随机推荐

  1. 关于Axure RP

    Axure RP 是一款专业的原型设计工具 用于快速创建应用软件的线框图.流程图.原型和规格说明文档 贴一张图

  2. Python使用requests模块下载图片

    MySQL中事先保存好爬取到的图片链接地址. 然后使用多线程把图片下载到本地. # coding: utf-8 import MySQLdb import requests import os imp ...

  3. MongoDB基操

    基本概念 database 数据库 包含多个collection collection 集合 包含多个文档document(类JSON对象) document 文档 一个文档对象中包含多个key-va ...

  4. RobHess的SIFT源码分析:imgfeatures.h和imgfeatures.c文件

    SIFT源码分析系列文章的索引在这里:RobHess的SIFT源码分析:综述 imgfeatures.h中有SIFT特征点结构struct feature的定义,除此之外还有一些特征点的导入导出以及特 ...

  5. Ubuntu 14.04 64bit下Caffe + Cuda6.5/Cuda7.0 安装配置教程

    http://www.embeddedlinux.org.cn/emb-linux/entry-level/201612/21-6005.html 随着深度学习快速发展的浪潮,许多有兴趣的工作者都转入 ...

  6. hadoop压缩和解压

    最近有一个hadoop集群上的备份需求.源文件有几百G,如果直接复制太占用磁盘空间.将文件从hadoop集群下载到本地,压缩之后再上传到hadoop则太耗时间.于是想到能否直接在HDFS文件系统上进行 ...

  7. stout代码分析之九:c++11容器新特性

    stout大量使用了c++11的一些新特性,使用这些特性有利于简化我们的代码,增加代码可读性.以下将对一些容器的新特性做一个总结.主要两方面: 容器的初始化,c++11中再也不用手动insert或者p ...

  8. 题解【luogu4168 [Violet]蒲公英】

    Description 给出一个长度为 \(n\) 序列 \(a\) ,\(m\) 次询问,每次询问区间 \([l,r]\) 里的众数(出现次数最多的数).若有多个,输出最小的. \(a_i \leq ...

  9. eclipse常见问题解决方案

    1.maven项目,启动报错ClassNotFoundException,原因是tomcat下\WEB-INF\classes目录中,java文件没有编译成class文件.解决方法: 在\WEB-IN ...

  10. POJ 3087 Shuffle'm Up DFS

    link:http://poj.org/problem?id=3087 题意:给你两串字串(必定偶数长),按照扑克牌那样的洗法(每次从S2堆底中拿第一张,再从S1堆底拿一张放在上面),洗好后的一堆可以 ...