如何收集aiohttp会话中的API响应并整合为统一结构
解决asyncio+aiohttp批量API响应收集与结构化问题
核心方案:利用asyncio.gather()直接收集响应
asyncio.gather(*tasks)本身会返回所有协程任务的执行结果列表,无需使用容易引发作用域错误的全局变量,直接接收这个返回值即可统一管理所有响应。
修正后的代码示例
1. 收集响应到列表
import asyncio import aiohttp async def get_url(session, url, timeout=300): async with session.get(url, timeout=timeout) as response: http = await response.text() print(str(http[:80])+'\n') return http async def async_payload_wrapper(): urls = ['https://google.com','https://yahoo.com'] async with aiohttp.ClientSession() as session: # 创建任务列表 tasks = [get_url(session, url) for url in urls] # 执行所有任务并收集结果到responses列表 responses = await asyncio.gather(*tasks) return responses if __name__ == '__main__': # Python 3.7+ 推荐用asyncio.run代替旧的事件循环写法 all_responses = asyncio.run(async_payload_wrapper()) # 此时all_responses就是所有API响应的列表 print("所有响应已收集完成,总数:", len(all_responses)) # 可直接访问单个响应,比如第一个:all_responses[0]
2. 转换为pandas DataFrame
如果需要结构化存储,直接将列表与对应URL组合成DataFrame:
import pandas as pd # 承接上面的all_responses urls = ['https://google.com','https://yahoo.com'] df = pd.DataFrame({ 'url': urls, 'response': all_responses }) print(df.head())
3. 高效写入文件
- 写入文本文件(批量写入比逐行快):
# 批量写入所有响应到文本文件 with open('responses.txt', 'w', encoding='utf-8') as f: # 每个响应按分隔符区分,比如换行加分割线 f.write('\n' + '-'*50 + '\n'.join(all_responses))
- 写入结构化文件(用pandas更高效):
# 写入CSV df.to_csv('responses.csv', index=False, encoding='utf-8') # 写入Parquet(比CSV更高效,适合大数据量) df.to_parquet('responses.parquet')
全局变量出错原因
你遇到的NameError或UnboundLocalError,是因为在函数内部使用全局变量时未声明global关键字,或者变量作用域混淆。但用asyncio.gather()返回结果的方式更简洁、安全,符合异步编程的最佳实践,避免了全局变量带来的副作用。
内容的提问来源于stack exchange,提问作者InnocentBystander
相关产品推荐
相关产品推荐

