- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章python aiohttp的使用详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1.aiohttp的简单使用(配合asyncio模块) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
asyncio,aiohttp
async
def
fetch_async(url):
print
(url)
async with aiohttp.request(
"get"
,url) as r:
reponse
=
await r.text(encoding
=
"utf-8"
)
#或者直接await r.read()不编码,直接读取,适合于图像等无法编码文件
print
(reponse)
tasks
=
[fetch_async(
'http://www.baidu.com/'
), fetch_async(
'http://www.chouti.com/'
)]
event_loop
=
asyncio.get_event_loop()
results
=
event_loop.run_until_complete(asyncio.gather(
*
tasks))
event_loop.close()
|
2.发起一个session请求 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import
asyncio,aiohttp
async
def
fetch_async(url):
print
(url)
async with aiohttp.clientsession() as session:
#协程嵌套,只需要处理最外层协程即可fetch_async
async with session.get(url) as resp:
print
(resp.status)
print
(await resp.text())
#因为这里使用到了await关键字,实现异步,所有他上面的函数体需要声明为异步async
tasks
=
[fetch_async(
'http://www.baidu.com/'
), fetch_async(
'http://www.cnblogs.com/ssyfj/'
)]
event_loop
=
asyncio.get_event_loop()
results
=
event_loop.run_until_complete(asyncio.gather(
*
tasks))
event_loop.close()
|
除了上面的get方法外,会话还支持post,put,delete....等 。
1
2
3
4
5
|
session.put(
'http://httpbin.org/put'
, data
=
b
'data'
)
session.delete(
'http://httpbin.org/delete'
)
session.head(
'http://httpbin.org/get'
)
session.options(
'http://httpbin.org/get'
)
session.patch(
'http://httpbin.org/patch'
, data
=
b
'data'
)
|
不要为每次的连接都创建一次session,一般情况下只需要创建一个session,然后使用这个session执行所有的请求.
每个session对象,内部包含了一个连接池,并且将会保持连接和连接复用(默认开启)可以加快整体的性能.
3.在url中传递参数(其实与requests模块使用大致相同) 。
只需要将参数字典,传入params参数中即可[code]import asyncio,aiohttp 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
asyncio,aiohttp
async
def
func1(url,params):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
print
(r.url)
print
(await r.read())
tasks
=
[func1(
'https://www.ckook.com/forum.php'
,{
"gid"
:
6
}),]
event_loop
=
asyncio.get_event_loop()
results
=
event_loop.run_until_complete(asyncio.gather(
*
tasks))
event_loop.close()
|
4.获取响应内容(由于获取响应内容是一个阻塞耗时过程,所以我们使用await实现协程切换) 。
(1)使用text()方法 。
1
2
3
4
5
6
|
async
def
func1(url,params):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
print
(r.url)
print
(r.charset)
#查看默认编码为utf-8
print
(await r.text())
#不编码,则是使用默认编码 使用encoding指定编码
|
(2)使用read()方法,不进行编码,为字节形式 。
1
2
3
4
5
|
async
def
func1(url,params):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
print
(r.url)
print
(await r.read())
|
(3)注意:text(),read()方法是把整个响应体读入内存,如果你是获取大量的数据,请考虑使用”字节流“(streamresponse) 。
5.特殊响应内容json(和上面一样) 。
1
2
3
4
5
6
|
async
def
func1(url,params):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
print
(r.url)
print
(r.charset)
print
(await r.json())
#可以设置编码,设置处理函数
|
6.字节流形式获取数据(不像text,read一次获取所有数据)注意:我们获取的session.get()是response对象,他继承于streamresponse 。
1
2
3
4
|
async
def
func1(url,params):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
print
(await r.content.read(
10
))
#读取前10字节
|
下面字节流形式读取数据,保存文件 。
1
2
3
4
5
6
7
8
9
10
11
|
async
def
func1(url,params,filename):
async with aiohttp.clientsession() as session:
async with session.get(url,params
=
params) as r:
with
open
(filename,
"wb"
) as fp:
while
true:
chunk
=
await r.content.read(
10
)
if
not
chunk:
break
fp.write(chunk)
tasks
=
[func1(
'https://www.ckook.com/forum.php'
,{
"gid"
:
6
},
"1.html"
),]
|
注意:
1
2
3
|
async with session.get(url,params
=
params) as r:
#异步上下文管理器
with
open
(filename,
"wb"
) as fp:
#普通上下文管理器
|
两者的区别:
在于异步上下文管理器中定义了 。
__aenter__和__aexit__方法 。
异步上下文管理器指的是在enter和exit方法处能够暂停执行的上下文管理器 。
为了实现这样的功能,需要加入两个新的方法:__aenter__和__aexit__。这两个方法都要返回一个 awaitable类型的值.
推文:异步上下文管理器 async with和异步迭代器async for 。
7.自定义请求头(和requests一样) 。
1
2
3
4
5
6
7
8
9
10
|
async
def
func1(url,params,filename):
async with aiohttp.clientsession() as session:
headers
=
{
'content-type'
:
'text/html; charset=utf-8'
}
async with session.get(url,params
=
params,headers
=
headers) as r:
with
open
(filename,
"wb"
) as fp:
while
true:
chunk
=
await r.content.read(
10
)
if
not
chunk:
break
fp.write(chunk)
|
8.自定义cookie 。
注意:对于自定义cookie,我们需要设置在clientsession(cookies=自定义cookie字典),而不是session.get()中 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class
clientsession:
def
__init__(
self
,
*
, connector
=
none, loop
=
none, cookies
=
none,
headers
=
none, skip_auto_headers
=
none,
auth
=
none, json_serialize
=
json.dumps,
request_class
=
clientrequest, response_class
=
clientresponse,
ws_response_class
=
clientwebsocketresponse,
version
=
http.httpversion11,
cookie_jar
=
none, connector_owner
=
true, raise_for_status
=
false,
read_timeout
=
sentinel, conn_timeout
=
none,
timeout
=
sentinel,
auto_decompress
=
true, trust_env
=
false,
trace_configs
=
none):
|
使用:
1
2
|
cookies
=
{
'cookies_are'
:
'working'
}
async with clientsession(cookies
=
cookies) as session:
|
10.获取网站的响应状态码 。
1
2
|
async with session.get(url) as resp:
print
(resp.status)
|
11.查看响应头 。
resp.headers 来查看响应头,得到的值类型是一个dict:
resp.raw_headers 查看原生的响应头,字节类型 。
12.查看重定向的响应头(我们此时已经到了新的网址,向之前的网址查看) 。
1
|
resp.history
#查看被重定向之前的响应头
|
13.超时处理 。
默认的io操作都有5分钟的响应时间 我们可以通过 timeout 进行重写:
1
2
|
async with session.get(
'https://github.com'
, timeout
=
60
) as r:
...
|
如果 timeout=none 或者 timeout=0 将不进行超时检查,也就是不限时长.
14.clientsession 用于在多个连接之间(同一网站)共享cookie,请求头等 。
1
2
3
4
5
6
7
|
async
def
func1():
cookies
=
{
'my_cookie'
:
"my_value"
}
async with aiohttp.clientsession(cookies
=
cookies) as session:
async with session.get(
"https://segmentfault.com/q/1010000007987098"
) as r:
print
(session.cookie_jar.filter_cookies(
"https://segmentfault.com"
))
async with session.get(
"https://segmentfault.com/hottest"
) as rp:
print
(session.cookie_jar.filter_cookies(https:
/
/
segmentfault.com))
|
1
2
3
4
|
set
-
cookie: phpsessid
=
web2~d8grl63pegika2202s8184ct2q
set
-
cookie: my_cookie
=
my_value
set
-
cookie: phpsessid
=
web2~d8grl63pegika2202s8184ct2q
set
-
cookie: my_cookie
=
my_value
|
我们最好使用session.cookie_jar.filter_cookies()获取网站cookie,不同于requests模块,虽然我们可以使用rp.cookies有可能获取到cookie,但似乎并未获取到所有的cookies.
1
2
3
4
5
6
7
8
9
10
11
12
|
async
def
func1():
cookies
=
{
'my_cookie'
:
"my_value"
}
async with aiohttp.clientsession(cookies
=
cookies) as session:
async with session.get(
"https://segmentfault.com/q/1010000007987098"
) as rp:
print
(session.cookie_jar.filter_cookies(
"https://segmentfault.com"
))
print
(rp.cookies)
#set-cookie: phpsessid=web2~jh3ouqoabvr4e72f87vtherkp6; domain=segmentfault.com; path=/ #首次访问会获取网站设置的cookie
async with session.get(
"https://segmentfault.com/hottest"
) as rp:
print
(session.cookie_jar.filter_cookies(
"https://segmentfault.com"
))
print
(rp.cookies)
#为空,服务端未设置cookie
async with session.get(
"https://segmentfault.com/newest"
) as rp:
print
(session.cookie_jar.filter_cookies(
"https://segmentfault.com"
))
print
(rp.cookies)
#为空,服务端未设置cookie
|
总结:
当我们使用rp.cookie时,只会获取到当前url下设置的cookie,不会维护整站的cookie 。
而session.cookie_jar.filter_cookies("https://segmentfault.com")会一直保留这个网站的所有设置cookies,含有我们在会话时设置的cookie,并且会根据响应修改更新cookie。这个才是我们需要的 。
而我们设置cookie,也是需要在aiohttp.clientsession(cookies=cookies)中设置 。
clientsession 还支持 请求头,keep-alive连接和连接池(connection pooling) 。
15.cookie的安全性 。
默认clientsession使用的是严格模式的 aiohttp.cookiejar. rfc 2109,明确的禁止接受url和ip地址产生的cookie,只能接受 dns 解析ip产生的cookie。可以通过设置aiohttp.cookiejar 的 unsafe=true 来配置:
1
2
|
jar
=
aiohttp.cookiejar(unsafe
=
true)
session
=
aiohttp.clientsession(cookie_jar
=
jar)
|
16.控制同时连接的数量(连接池) 。
tcpconnector维持链接池,限制并行连接的总量,当池满了,有请求退出再加入新请求 。
1
2
3
4
5
6
7
8
9
|
async
def
func1():
cookies
=
{
'my_cookie'
:
"my_value"
}
conn
=
aiohttp.tcpconnector(limit
=
2
)
#默认100,0表示无限
async with aiohttp.clientsession(cookies
=
cookies,connector
=
conn) as session:
for
i
in
range
(
7
,
35
):
url
=
"https://www.ckook.com/list-%s-1.html"
%
i
async with session.get(url) as rp:
print
(
'---------------------------------'
)
print
(rp.status)
|
限制同时打开限制同时打开连接到同一端点的数量((host, port, is_ssl) 三的倍数),可以通过设置 limit_per_host 参数:
limit_per_host: 同一端点的最大连接数量。同一端点即(host, port, is_ssl)完全相同 。
1
|
conn
=
aiohttp.tcpconnector(limit_per_host
=
30
)
#默认是0
|
在协程下测试效果不明显 。
17.自定义域名解析地址 。
我们可以指定域名服务器的 ip 对我们提供的get或post的url进行解析:
1
2
3
4
|
from
aiohttp.resolver
import
asyncresolver
resolver
=
asyncresolver(nameservers
=
[
"8.8.8.8"
,
"8.8.4.4"
])
conn
=
aiohttp.tcpconnector(resolver
=
resolver)
|
18.设置代理 。
aiohttp支持使用代理来访问网页:
1
2
3
4
|
async with aiohttp.clientsession() as session:
async with session.get(
"http://python.org"
,
proxy
=
"http://some.proxy.com"
) as resp:
print
(resp.status)
|
当然也支持需要授权的页面:
1
2
3
4
5
6
|
async with aiohttp.clientsession() as session:
proxy_auth
=
aiohttp.basicauth(
'user'
,
'pass'
)
#用户,密码
async with session.get(
"http://python.org"
,
proxy
=
"http://some.proxy.com"
,
proxy_auth
=
proxy_auth) as resp:
print
(resp.status)
|
或者通过这种方式来验证授权:
1
2
|
session.get(
"http://python.org"
,
proxy
=
http:
/
/
user:
pass
@some.proxy.com)
|
19.post传递数据的方法 。
(1)模拟表单 。
1
2
3
4
|
payload
=
{
'key1'
:
'value1'
,
'key2'
:
'value2'
}
async with session.post(
'http://httpbin.org/post'
,
data
=
payload) as resp:
print
(await resp.text())
|
注意:data=dict的方式post的数据将被转码,和form提交数据是一样的作用,如果你不想被转码,可以直接以字符串的形式 data=str 提交,这样就不会被转码.
(2)post json 。
1
2
3
|
payload
=
{
'some'
:
'data'
}
async with session.post(url, data
=
json.dumps(payload)) as resp:
|
其实json.dumps(payload)返回的也是一个字符串,只不过这个字符串可以被识别为json格式 。
(3)post 小文件 。
1
2
3
4
|
url
=
'http://httpbin.org/post'
files
=
{
'file'
:
open
(
'report.xls'
,
'rb'
)}
await session.post(url, data
=
files)
|
1
2
3
4
5
6
7
8
|
url
=
'http://httpbin.org/post'
data
=
formdata()
data.add_field(
'file'
,
open
(
'report.xls'
,
'rb'
),
filename
=
'report.xls'
,
content_type
=
'application/vnd.ms-excel'
)
await session.post(url, data
=
data)
|
如果将文件对象设置为数据参数,aiohttp将自动以字节流的形式发送给服务器.
(4)post 大文件 。
aiohttp支持多种类型的文件以流媒体的形式上传,所以我们可以在文件未读入内存的情况下发送大文件.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@aiohttp
.streamer
def
file_sender(writer, file_name
=
none):
with
open
(file_name,
'rb'
) as f:
chunk
=
f.read(
2
*
*
16
)
while
chunk:
yield
from
writer.write(chunk)
chunk
=
f.read(
2
*
*
16
)
# then you can use `file_sender` as a data provider:
async with session.post(
'http://httpbin.org/post'
,
data
=
file_sender(file_name
=
'huge_file'
)) as resp:
print
(await resp.text())
|
(5)从一个url获取文件后,直接post给另一个url 。
1
2
|
r
=
await session.get(
'http://python.org'
)
await session.post(
'http://httpbin.org/post'
,data
=
r.content)
|
(6)post预压缩数据 。
在通过aiohttp发送前就已经压缩的数据, 调用压缩函数的函数名(通常是deflate 或 zlib)作为content-encoding的值:
1
2
3
4
5
6
7
|
async
def
my_coroutine(session, headers, my_data):
data
=
zlib.compress(my_data)
headers
=
{
'content-encoding'
:
'deflate'
}
async with session.post(
'http://httpbin.org/post'
,
data
=
data,
headers
=
headers)
pass
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://www.cnblogs.com/ssyfj/p/9222342.html 。
最后此篇关于python aiohttp的使用详解的文章就讲到这里了,如果你想了解更多关于python aiohttp的使用详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运
主要是讲下Mongodb的索引的查看、创建、删除、类型说明,还有就是Explain执行计划的解释说明。 可以转载,但请注明出处。  
1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发。 2>循环服务器和并发服务器
详解 linux中的关机和重启命令 一 shutdown命令 shutdown [选项] 时间 选项: ?
首先,将json串转为一个JObject对象: ? 1
matplotlib官网 matplotlib库默认英文字体 添加黑体(‘SimHei')为绘图字体 代码: plt.rcParams['font.sans-serif']=['SimHei'
在并发编程中,synchronized关键字是常出现的角色。之前我们都称呼synchronized关键字为重量锁,但是在jdk1.6中对synchronized进行了优化,引入了偏向锁、轻量锁。本篇
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。  
实例如下: ? 1
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存
argument是javascript中函数的一个特殊参数,例如下文,利用argument访问函数参数,判断函数是否执行 复制代码 代码如下: <script
一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,googl
今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1、PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 funct
摘要:虚拟机安装时一般都采用最小化安装,默认没有lspci工具。一台测试虚拟网卡性能的虚拟机,需要lspci工具来查看网卡的类型。本文描述了在一个虚拟机中安装lspci工具的具体步骤。 由于要测试
1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
目录 算术运算符 基本四则运算符 增量赋值运算符 自增/自减运算符 关系运算符 逻
如下所示: ? 1
MapperScannerConfigurer之sqlSessionFactory注入方式讲解 首先,Mybatis中的有一段配置非常方便,省去我们去写DaoImpl(Dao层实现类)的时间,这个
Linux的网络虚拟化是LXC项目中的一个子项目,LXC包括文件系统虚拟化,进程空间虚拟化,用户虚拟化,网络虚拟化,等等,这里使用LXC的网络虚拟化来模拟多个网络环境。 本文从基本的网络设备讲
? 1
我是一名优秀的程序员,十分优秀!