我尝试使用 aiohttp 拉取多个响应请求,但出现属性错误。
我的代码看起来像这样,我不得不掩盖它,因为我使用的是私有 api。
import aiohttp
import asyncio
async def get_data(session, x):
try:
async with session.get(url=f'https://api.abc.com/{x}') as response:
data = await response.json()
return data.json()
except Exception as e:
print("Unable to get url {} due to {}.".format(ticker, e.__class__))
async def main(datas):
async with aiohttp.ClientSession() as session:
ret = await asyncio.gather(*[get_data(data, session) for data in datas])
return ret
datas = ['x1', 'x2', 'x3', 'x4']
resukts = asyncio.run(main(datas))
我的错误看起来像这样,
Unable to get url <aiohttp.client.ClientSession object at 0x1013f6ee0> due to <class 'AttributeError'>.
Unable to get url <aiohttp.client.ClientSession object at 0x1013f6ee0> due to <class 'AttributeError'>.
Unable to get url <aiohttp.client.ClientSession object at 0x1013f6ee0> due to <class 'AttributeError'>.
Unable to get url <aiohttp.client.ClientSession object at 0x1013f6ee0> due to <class 'AttributeError'>.
我做错了什么?
我希望能够并行或异步地从 api 获取响应。
response.json() 已经返回解析的 JSON 数据,因此不需要再次对数据调用 .json() ,并且会引发 AttributeError 。
尝试这样
import aiohttp
import asyncio
async def get_data(session, x):
try:
async with session.get(url=f'https://api.abc.com/{x}') as response:
data = await response.json()
return data # Return the parsed JSON data directly, no need for .json()
except Exception as e:
print("Unable to get url {} due to {}.".format(x, e.__class__))
async def main(datas):
async with aiohttp.ClientSession() as session:
ret = await asyncio.gather(*[get_data(session, data) for data in datas]) # Pass session and data in the correct order
return ret
datas = ['x1', 'x2', 'x3', 'x4']
results = asyncio.run(main(datas)) # Correct the variable name to "results"
OP要求一种以字典格式返回结果的方法: 这就是你可以做到的:
import aiohttp
import asyncio
async def get_data(session, x):
try:
async with session.get(url=f'https://api.abc.com/{x}') as response:
data = await response.json()
return data
except Exception as e:
print("Unable to get url {} due to {}.".format(x, e.__class__))
return None
async def main(datas):
async with aiohttp.ClientSession() as session:
ret = await asyncio.gather(*[get_data(session, data) for data in datas])
return {datas[i]: ret[i] for i in range(len(datas))} # Return the results as a dictionary
datas = ['x1', 'x2', 'x3', 'x4']
results = asyncio.run(main(datas))