asyncio与aiohttp爬虫报错RuntimeError: await wasn't used with future如何解决?
问题原因
核心错误是变量名拼写错误:
在get_all函数中,你把存储所有异步任务的列表变量tasks(复数)误写为了单数的task:
# 错误写法 results = await asyncio.gather(*task) # 正确写法 results = await asyncio.gather(*tasks)
错误触发逻辑:循环中你每次创建单个task对象存入tasks列表,循环结束后task变量指向的是最后一次循环创建的单个Task对象,对单个Task做*解包操作会得到不符合asyncio.gather预期的参数,因此触发RuntimeError: await wasn't used with future报错,和服务器、循环内await写法无关。
其他存在的问题
- 你定义了
asyncio.Semaphore(1)但未实际使用,当前代码会同时发起所有请求,很容易被目标站点反爬拦截、触发超时失败 main函数中拿到返回的data后没有return该变量,最终你打印的results会是None,无法拿到爬取结果
修正后的完整代码
import asyncio import aiohttp # 用信号量控制并发数的get_page实现 async def get_page(session, x, sem): async with sem: async with session.get(f'https://disclosure.bursamalaysia.com/FileAccess/viewHtml?e={x}') as r: return await r.text() async def get_all(session, urls): tasks =[] sem = asyncio.Semaphore(5) # 可以根据站点承受能力调整并发数 count = 0 for x in urls: count +=1 task = asyncio.create_task(get_page(session, x, sem)) tasks.append(task) print(count,'-ID-',x,'|', end=' ') results = await asyncio.gather(*tasks) return results async def main(urls): async with aiohttp.ClientSession() as session: data = await get_all(session, urls) return data # 补上返回值 if __name__ == '__main__': urls = titlelink # 注意确保titlelink变量已提前定义 results = asyncio.run(main(urls)) print(results)
排查方向参考
- 遇到异步相关报错先看堆栈指向的行,确认传入的参数类型是否符合函数要求
- 并发请求场景一定要做好并发数控制,避免触发站点反爬规则
- 函数返回值要逐层检查,避免上层调用拿不到预期结果
内容的提问来源于stack exchange,提问作者Yazid Yaakub
相关产品推荐
相关产品推荐

