【PY模块】aiohttp 使用 [ Python极客 ]
大数据男孩 文章 正文
明妃
{{nature("2022-08-14 17:23:19")}}更新主要特点
- 支持
异步客户端
和异步服务端
- 支持开箱即用的
WebSocket 服务端
和WebSocket 客服端
- 服务端还支持 中间件(Middlewares)和信号(Signals)
初始
安装
pip install aiohttp
客户端
import asyncio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
res = await session.get(url='https://bigdataboy.cn')
print(res)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
[]()
服务端
本文不会介绍
from aiohttp import web
async def handle(request):
name = request.match_info.get('name', "bigdataboy")
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=app, host='127.0.0.1', port=8080)
[]()
快速上手
发出请求
import asyncio, aiohttp
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())
其他请求方式
session.post('http://httpbin.org/post', data=b'data')
session.put('http://httpbin.org/put', data='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='data')
为了请求
同一个网站
更方便
async with aiohttp.ClientSession(base_url='http://httpbin.org') as session:
async with session.get(url='/get') as resp:
print(resp.status) # 或 调用其他函数
async with session.post(url='/post', data='data') as resp:
print(resp.status)
async with session.put(url='/put', data='data') as resp:
print(resp.status)
提示 & 技巧
一个站点
的使用一个会话
,==不要==为一个请求
创建一个会话
会话内部
包含一个连接池
。连接重用
和保持活动
(默认情况下都打开)可以提高整体性能。-
不使用上下文形式
需要收到关闭会话
session = aiohttp.ClientSession()
async with session.get('...'):
# ...
await session.close()
参数传递
# GET
params = {'k': 'v'}
params = [('k', 'v'), ('k1', 'v1')]
async with session.get(url='/get', params=params) as resp:
pass
# POST
data = 'str'
async with session.post(url='/post', data=data) as resp:
pass
json = {'k': 'v'}
async with session.post(url='/post', json=json) as resp:
pass
响应内容
async with session.get('https://bigdataboy.cn') as resp:
# 状态码
resp.status
#文本解码
await resp.text(encoding='utf-8') # 指定解码方式
# json 解码
await resp.json()
# 二进制解码
await resp.read()
流式响应内容
当响应文件过于庞大,使用
read()
、json()
、text()
会把内容全部加载到内存,这是愚蠢的做法,应该使用流式响应。
async with session.get('https://api.github.com/events') as resp:
with open('./xx', 'wb') as fd:
chunk_size = 10
async for chunk in resp.content.iter_chunked(chunk_size):
fd.write(chunk)
网络套接字(WebSocket)
# 使用小蝌蚪聊天室测试
async with session.ws_connect('ws://kedou.workerman.net:8280/') as ws:
async for msg in ws:
print(msg)
await ws.send_str('1122') # 发送数据
# await ws.send_json()
# await ws.send_json()
超时
# 单位 秒 默认超时 300 秒
timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession(timeout=timeout) as session:
...
# 会覆盖 session 设置的超时
async with session.get(url, timeout=timeout) as resp:
...
自定义请求头
# 会话请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
}
async with aiohttp.ClientSession(headers=headers) as session:
...
# 单独设置会 合并 会话请求头
async with session.get(url='http://httpbin.org/headers', headers=headers) as resp:
...
自定义 Cookie
url = 'http://httpbin.org/cookies'
cookies = {'cookies_are': 'working'}
async with aiohttp.ClientSession(cookies=cookies) as session:
# 添加 Cookies
session.cookie_jar.update_cookies(cookies={'k1': 'v1'})
# 单独设置会 合并到 会话Cookies
async with session.get(url,cookies={'k': 'v'}) as resp:
res = await resp.json()
print(res)
[]()
重定向
禁止重定向
allow_redirects=False
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
print(resp.history) # 重定向历史元祖
print(resp.history[0])
print(resp.history[0].url)
代理
aiohttp 还
不能很好
的支持https代理
# HTTP 代理
async with aiohttp.ClientSession() as session:
async with session.get(url=url,
proxy='http://127.0.0.1:7890') 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://127.0.0.1:7890",
proxy_auth=proxy_auth) as resp:
print(resp.status)
# socks 代理 pip install aiohttp_socks
from aiohttp_socks import ProxyConnector
conn = ProxyConnector.from_url('socks5://127.0.0.1:7890')
async with aiohttp.ClientSession(connector=conn, headers=headers) as session:
...
小技巧
推荐写法
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, 'https://bigdataboy.cn')
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
{{nature('2020-01-02 16:47:07')}} {{format('12641')}}人已阅读
{{nature('2019-12-11 20:43:10')}} {{format('9527')}}人已阅读
{{nature('2019-12-26 17:20:52')}} {{format('7573')}}人已阅读
{{nature('2019-12-26 16:03:55')}} {{format('5017')}}人已阅读
目录
标签云
一言
评论 0
{{userInfo.data?.nickname}}
{{userInfo.data?.email}}