aiohttp中ClientResponse处理报错及asyncio.gather顺序疑问
aiohttp代理测试工具问题解答
问题1:为何仍出现ClientResponse.text协程未被await的警告?如何编写响应处理函数?
你用asyncio.gather等待的是session_request任务完成,但session_request仅返回了ClientResponse对象,并没有读取响应内容。r.text()是异步方法(协程),必须通过await才能执行,你在原handle_response里直接调用str(r.text()),只是把协程对象转成了字符串,根本没触发它执行,所以会报未await的警告。
下面是修正后的异步响应处理函数及相关代码调整:
修正后的handle_response异步函数
async def handle_response(result) -> bool | str: # 处理asyncio.gather返回的异常(如超时、连接失败) if isinstance(result, Exception): return False # 确保是ClientResponse实例 if not hasattr(result, 'status'): return False match result.status: case 200: try: # 必须await text()协程 return await result.text() except Exception: return False case _: return False
调整async_test_proxies中的循环逻辑
因为handle_response变成了异步函数,调用时需要加await:
async def async_test_proxies(proxies: list, url: str = 'icanhazip.com', enable_prints: bool = False) -> list: def is_proxy_works(html: str, proxy: str, url: str, enable_prints: bool) -> bool: ... # 你的原有逻辑 proxies_works = [] async with ClientSession() as s: tasks = [asyncio.create_task(session_request(s, url, proxy)) for proxy in proxies] results = await asyncio.gather(*tasks, return_exceptions=True) for i in range(len(results)): # 异步调用handle_response r = await handle_response(results[i]) if isinstance(r, str): if is_proxy_works(r, proxies[i], url, enable_prints): proxies_works.append(proxies[i]) if enable_prints: print(f'{len(proxies_works)}/{len(proxies)} proxies works') return proxies_works
问题2:asyncio.gather()是否保证返回结果顺序与输入任务一致?
是的,asyncio.gather会严格按照你传入任务的顺序返回结果,和任务实际完成的先后无关。比如你传入任务列表[task_a, task_b, task_c],返回的结果列表第一个元素是task_a的执行结果,第二个是task_b的,第三个是task_c的,哪怕task_b比task_a先完成。
内容的提问来源于stack exchange,提问作者555Russich
相关产品推荐
相关产品推荐

