Python异步逐行读文件与异步请求执行不符合预期问题咨询
问题分析与解决
你的代码没实现真正的异步并发,这才导致了等待10秒的情况。
原因说明
你在async for循环里,每处理一行就创建httpx.AsyncClient并await单个请求——这相当于串行执行:每个请求必须等上一个完全结束(不管成功还是超时失败),才会启动下一个。第四个请求被ISP屏蔽后会一直阻塞到超时,后面的第五、第六个请求根本没机会开始,自然要等10秒报错后才会继续执行。
修正方案
要实现你预期的“成功请求先返回结果,失败请求最后报错”的效果,需要把所有请求做成并发任务同时执行,并且让错误任务不中断其他任务。修正后的代码如下:
import asyncio import aiofiles import httpx async def fetch_url(client, url): try: response = await client.get(url) return f"{response} for {url}" except Exception as e: return f"Error for {url}: {str(e)}" async def parsing_bsc_1inch(): # 先读取所有URL到列表 urls = [] async with aiofiles.open('test.txt', mode='r') as f: async for line in f: url = line.rstrip() if url: urls.append(url) # 复用一个AsyncClient,避免重复创建连接 async with httpx.AsyncClient() as client: # 为每个URL创建异步任务 tasks = [fetch_url(client, url) for url in urls] # 并发执行所有任务,return_exceptions=True让错误不打断其他任务 results = await asyncio.gather(*tasks, return_exceptions=True) # 输出所有结果 for result in results: print(result) asyncio.run(parsing_bsc_1inch())
修正逻辑说明
- 先一次性读取所有URL,避免边读边执行的串行限制
- 复用同一个
httpx.AsyncClient,减少连接建立的开销,符合HTTP客户端的最佳实践 - 用
asyncio.gather并发执行所有请求任务,return_exceptions=True参数确保即使某个请求失败,其他请求仍能正常完成 - 所有请求的结果(成功或错误)会被统一收集,执行完成后一起输出,这样就能看到成功的请求先返回结果,失败的请求的错误信息会在最后出现(或和其他结果混合,取决于实际执行时长)
内容的提问来源于stack exchange,提问作者deadinsideclown
相关产品推荐
相关产品推荐

