Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >python aiohttp_python aiohttp的使用详解

python aiohttp_python aiohttp的使用详解

作者头像
全栈程序员站长
发布于 2022-11-17 10:05:36
发布于 2022-11-17 10:05:36
1.7K0
举报

1.aiohttp的简单使用(配合asyncio模块)

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请求

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….等

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

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()方法

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()方法,不进行编码,为字节形式

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(和上面一样)

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

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字节

下面字节流形式读取数据,保存文件

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”),]

注意:

async with session.get(url,params=params) as r:  #异步上下文管理器

with open(filename,”wb”) as fp:  #普通上下文管理器

两者的区别:

在于异步上下文管理器中定义了

__aenter__和__aexit__方法

异步上下文管理器指的是在enter和exit方法处能够暂停执行的上下文管理器

为了实现这样的功能,需要加入两个新的方法:__aenter__和__aexit__。这两个方法都要返回一个 awaitable类型的值。

7.自定义请求头(和requests一样)

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()中

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):

使用:

cookies = {‘cookies_are’: ‘working’}

async with ClientSession(cookies=cookies) as session:

10.获取网站的响应状态码

async with session.get(url) as resp:

print(resp.status)

11.查看响应头

resp.headers 来查看响应头,得到的值类型是一个dict:

resp.raw_headers  查看原生的响应头,字节类型

12.查看重定向的响应头(我们此时已经到了新的网址,向之前的网址查看)

resp.history  #查看被重定向之前的响应头

13.超时处理

默认的IO操作都有5分钟的响应时间 我们可以通过 timeout 进行重写:

async with session.get(‘https://github.com’, timeout=60) as r:

如果 timeout=None 或者 timeout=0 将不进行超时检查,也就是不限时长。

14.ClientSession 用于在多个连接之间(同一网站)共享cookie,请求头等

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))

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。

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 来配置:

jar = aiohttp.CookieJar(unsafe=True)

session = aiohttp.ClientSession(cookie_jar=jar)

16.控制同时连接的数量(连接池)

TCPConnector维持链接池,限制并行连接的总量,当池满了,有请求退出再加入新请求

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)完全相同

conn = aiohttp.TCPConnector(limit_per_host=30)#默认是0

在协程下测试效果不明显

17.自定义域名解析地址

我们可以指定域名服务器的 IP 对我们提供的get或post的url进行解析:

from aiohttp.resolver import AsyncResolver

resolver = AsyncResolver(nameservers=[“8.8.8.8”, “8.8.4.4”])

conn = aiohttp.TCPConnector(resolver=resolver)

18.设置代理

aiohttp支持使用代理来访问网页:

async with aiohttp.ClientSession() as session:

async with session.get(“http://python.org”,

proxy=”http://some.proxy.com”) as resp:

print(resp.status)

当然也支持需要授权的页面:

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)

或者通过这种方式来验证授权:

session.get(“http://python.org”,

proxy=http://user:pass@some.proxy.com)

19.post传递数据的方法

(1)模拟表单

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

payload = {‘some’: ‘data’}

async with session.post(url, data=json.dumps(payload)) as resp:

其实json.dumps(payload)返回的也是一个字符串,只不过这个字符串可以被识别为json格式

(3)post 小文件

url = ‘http://httpbin.org/post’

files = {‘file’: open(‘report.xls’, ‘rb’)}

await session.post(url, data=files)

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支持多种类型的文件以流媒体的形式上传,所以我们可以在文件未读入内存的情况下发送大文件。

@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

r = await session.get(‘http://python.org’)

await session.post(‘http://httpbin.org/post’,data=r.content)

(6)post预压缩数据

在通过aiohttp发送前就已经压缩的数据, 调用压缩函数的函数名(通常是deflate 或 zlib)作为content-encoding的值:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/223053.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
aiohttp 异步http请求-4.文件上传multipart/form-data
前言 文件上传接口,post 请求参数类型content-type:multipart/form-data,上传文件分2种情况 小文件上传,可以直接用open函数读取 大文件上传,aiohttp支持多种类型的文件以流媒体的形式上传 官方文档示例 上传 multipart 类型 url = 'http://httpbin.org/post' files = {'file': open('report.xls', 'rb')} await session.post(url, data=files) 也可以明确
上海-悠悠
2022/04/22
3.1K0
aiohttp 异步http请求-4.文件上传multipart/form-data
大型fastapi项目实战 高并发请求神器之aiohttp(下)
1.先通过 event_loop = asyncio.get_event_loop() 创建了一个事件循环 2.通过 asyncio.gather 接受多个 future 或 coro 组成的列表 任务 3.通过 event_loop.run_until_complete(task) 我们 就开启 事件循环 直到这个任务执行结束。 4.async with aiohttp.ClientSession() as session: 是创建了一个异步的网络请求的上线文管理具柄 5.async with session.get('http://www.baidu.com') as resp: 异步请求数据 6.res = await resp.text() 异步的接收数据 再解释一下两个关键词 1.async 如果一个函数被这个async 关键词修饰 那这个函数就是一个 future object 2.await 协程对象执行到这个关键词定义之处就会做挂起操作,原理是与yield /yield from 类似的。
python编程从入门到实践
2021/03/03
3.4K0
大型fastapi项目实战 高并发请求神器之aiohttp(下)
python 基于aiohttp的异步爬虫实战
钢铁知识库,一个学习python爬虫、数据分析的知识库。人生苦短,快用python。
钢铁知识库
2022/09/19
1K0
想提高爬虫效率?aiohttp 了解下
对于爬虫程序,我们往往会很关注其爬虫效率。影响爬虫效率有几个因素有,是否使用多线程,I/O 操作,是否同步执行等。其中 I/O 操作、同步执行是最影响爬虫效率的。
猴哥yuri
2018/08/16
1.2K0
大型fastapi项目实战 高并发请求神器之aiohttp(上) [建议收藏]
在 Python 众多的 HTTP 客户端中,最有名的莫过于 requests、aiohttp 和 httpx。在不借助其他第三方库的情况下,requests 只能发送同步请求;aiohttp 只能发送异步请求;httpx 既能发送同步请求,又能发送异步请求。在并发量大的情况下,如何高效的处理数据,异步是我们的优选,今天我们主要详解的是在生产环境广泛使用的 aiohttp。
python编程从入门到实践
2021/02/04
10.6K0
python3异步爬虫 ——aiohttp模板使用
一.简单使用和讲解 import aiohttp import asyncio async def fetch(client): async with client.get('http://httpbin.org/get') as resp: assert resp.status == 200 return await resp.text() async def main(): async with aiohttp.ClientSession() as
小小咸鱼YwY
2020/10/27
1.3K0
aiohttp 异步http请求-10.ClientSession自定义请求Cookie
前言 要将自己的 cookie 发送到服务器,可以使用构造函数的cookies 参数ClientSession 自定义cookie cookie 定义成字典键值对格式,传参到ClientSession url = 'http://httpbin.org/cookies' cookies = {'cookies_are': 'working'} async with ClientSession(cookies=cookies) as session: async with session.get(ur
上海-悠悠
2022/04/27
1.9K0
aiohttp 异步http请求-10.ClientSession自定义请求Cookie
aiohttp 异步http请求-2.post 请求application/json和data
前言 aiohttp 发送post请求,body类型的常见的类型传参: application/json application/x-www-form-urlencode application/json POST 请求接口报文示例,Content-Type类型是application/json POST /api/v1/login/ HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-
上海-悠悠
2022/04/21
6.4K0
剖析灵魂,为什么aiohttp默认的写法那么慢?
在上一篇文章中,我们提到了 aiohttp 官方文档中的默认写法速度与 requests 单线程请求没有什么区别,需要通过使用asyncio.wait来加速 aiohttp 的请求。今天我们来探讨一下这背后的原因。
青南
2019/12/25
1.9K0
剖析灵魂,为什么aiohttp默认的写法那么慢?
Python网络请求-aiohttp
在 Python 众多的 HTTP 客户端中,最有名的莫过于requests、aiohttp和httpx。
码客说
2021/11/29
1.3K0
AIOHTTP的实战(一)
aiohttp是基于asyncio和Python的异步HTTP客户端以及服务器,在这里主要介绍aiohttp在客户端应用请求中的案例应用和案例实战。在使用前需要安装该第三方的库,安装的命令为:
无涯WuYa
2020/07/24
1.4K0
aiohttp 异步http请求-1.快速入门 get 请求示例
前言 在 python 的众多 http 请求库中,大家最熟悉的就是 requests 库了,requests 库上手非常容易,适合入门学习。 如果平常工作中对发请求不追求效率和并发的情况下,requests 完全可以满足大部分需求。但是想发大量的请求,比如几万个请求的时候,可能需要等待几个小时,requests 库就不能满足需求了。 初学者建议先学习requests 库,熟练掌握requests 库才能更好的学习 aiohttp 异步框架。 同步与异步 requests只能发送同步请求,aiohttp只能
上海-悠悠
2022/04/21
2.4K0
aiohttp 异步http请求-1.快速入门 get 请求示例
Python异步请求对大数量请求也太友好了,Python异步的复习
刚进入公司,由于对抓取这块比较有经验,然后刚好业务也是有一部分抓取的。于是我的任务就先是这些数据采集。 采用异步请求之后的效果:
SingYi
2022/07/13
3.5K1
Python异步请求对大数量请求也太友好了,Python异步的复习
强大的异步爬虫 with aiohttp
看到现在网络上大多讲的都是requests、scrapy,却没有说到爬虫中的神器:aiohttp
小歪
2018/07/25
1.1K0
Python为什么要使用异步来进行爬取?
有些时候,我们使用爬虫下载图片,视频什么的,而下载这些文件都是一个耗时的操作。如果采用之前那种同步的方式下载。那效率肯会特别慢。这时候我们就可以考虑使用多线程的方式来下载这类文件。
@莜莜
2021/03/31
4960
aiohttp 异步http请求-7.https请求报SSL问题
默认情况下, aiohttp对 HTTPS 协议使用严格检查。有些同学电脑上请求https请求可能会报ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]
上海-悠悠
2022/04/26
4K0
python︱用asyncio、aiohttp实现异步及相关案例
Asyncio 是并发(concurrency)的一种方式。对 Python 来说,并发还可以通过线程(threading)和多进程(multiprocessing)来实现。Asyncio 并不能带来真正的并行(parallelism)。当然,因为 GIL(全局解释器锁)的存在,Python 的多线程也不能带来真正的并行。 .
悟乙己
2019/05/26
2.3K0
异步爬虫实践攻略:利用Python Aiohttp框架实现高效数据抓取
异步爬虫是指在进行数据抓取时能够实现异步IO操作的爬虫程序。传统的爬虫程序一般是同步阻塞的,即每次发送请求都需要等待响应返回后才能进行下一步操作,效率较低。而异步爬虫可以在发送请求后不阻塞等待响应,而是继续执行其他任务,从而提升了数据抓取效率。
小白学大数据
2024/06/08
2720
为 aiohttp 爬虫注入灵魂
听说过异步爬虫的同学,应该或多或少听说过aiohttp这个库。它通过 Python 自带的async/await实现了异步爬虫。
青南
2019/12/25
1K0
为 aiohttp 爬虫注入灵魂
aiohttp 异步http请求-9.ClientSession自定义请求头部
前言 ClientSession是所有客户端 API 操作的核心和主要入口点。会话包含 cookie 存储和连接池,因此 cookie 和连接在同一会话发送的 HTTP 请求之间共享。 自定义请求头部 如果您需要将 HTTP 标头添加到请求中,请将它们传递给 headers 参数。如在请求头部添加"Content-Type": "application/json" headers = { "Content-Type": "application/json" } 完整代码: imp
上海-悠悠
2022/04/27
2.3K0
相关推荐
aiohttp 异步http请求-4.文件上传multipart/form-data
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档