aiohttp 非同步http請求-2.post 請求application/json和application/x-www-form-urlencode
阿新 • • 發佈:2022-04-20
前言
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-alive Content-Length: 42 Content-Type: application/json Host: 127.0.0.1:8000 User-Agent: HTTPie/1.0.3 { "password": "123456", "username": "test" }
於是可以使用ClientSession.post()接受 json引數
import aiohttp import asyncio async def main(): async with aiohttp.ClientSession('http://127.0.0.1:8000') as session: body = { "password": "123456", "username": "test" } async with session.post('/api/v1/login', json=body) as resp: print(resp.url) print(await resp.text()) loop = asyncio.get_event_loop() loop.run_until_complete(main())
執行結果
http://127.0.0.1:8000/api/v1/login
{"code": 0, "msg": "login success!", "username": "test", "token": "ff7b608ed22407a4cd4d2f7beb1bfe9015574bdc"}
預設情況下,會話使用 python 的標準json模組進行序列化。但可以使用不同的 serializer.
ClientSession接受json_serialize 引數:
import ujson async with aiohttp.ClientSession( json_serialize=ujson.dumps) as session: await session.post(url, json={'test': 'object'})
筆記:ujson 比json快,但有些不相容
JSON 響應內容
有一個內建的 JSON 解碼器,以防您處理 JSON 資料:
async with session.post('/api/v1/login', json=body) as resp:
print(await resp.json())
如果json解碼失敗,會丟擲異常ContentTypeError
raise ContentTypeError(
aiohttp.client_exceptions.ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/html; charset=utf-8'
使用.json()
解碼器後,會將返回的內容解析成python裡面的dict型別,方便取值
async with session.post('/api/v1/login', json=body) as resp:
res = await resp.json()
token = res['token']
print('token: ', token)
application/x-www-form-urlencode
POST 請求介面報文示例,Content-Type型別是application/x-www-form-urlencode
POST /api/v4/login HTTP/1.1
Content-Length: 29
Content-Type: application/x-www-form-urlencoded
username=test&password=123456
html上form表單資料的提交,只需傳一個data引數即可
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession('http://127.0.0.1:8000') as session:
body = {
"password": "123456",
"username": "test"
}
async with session.post('/api/v4/login', data=body) as resp:
print(await resp.json())
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
執行結果
{'code': 0, 'msg': 'login success!', 'username': 'test', 'token': '408434b72328ea6740f7f2c260a1c3f97be82fab'}
總結
如果要傳送未進行表單編碼的資料,可以通過傳遞 bytes 預設情況下內容型別設定為 'application/octet-stream':
async with session.post(url, data=b'\x00Binary-data\x00') as resp:
...
如果要傳送 JSON 資料:
async with session.post(url, json={'example': 'test'}) as resp:
...
要傳送具有適當內容型別的文字,只需使用data引數
async with session.post(url, data='Тест') as resp:
...