You need to enable JavaScript to run this app. Python asyncio使用run_in_executor时无法获取scraper返回结果列表的问题
优惠活动
大模型
产品
解决方案
定价
更多

Python asyncio使用run_in_executor时无法获取scraper返回结果列表的问题

代码运行异常的根因

存在的核心问题

  • get_toner 函数调用 loop.run_in_executor 后,没有将该方法返回的Future对象向外传递,所有提交到executor的任务都作为临时值被丢弃,无法进入后续的结果收集链路。
  • 读取事件循环任务集合的时机错误:刚提交完所有executor调用、任务还未被事件循环正式调度时,就调用asyncio.all_tasks(loop)获取任务列表,此时拿到的是空集合,最终gather收集到的自然是空列表。
  • 缺少executor的实际初始化逻辑,直接使用未定义的executor对象会直接触发运行报错。

可正常运行的修正代码

import asyncio
from concurrent.futures import ThreadPoolExecutor

# 初始化线程池,可根据爬取需求调整并发数
executor = ThreadPoolExecutor(max_workers=10)
loop = asyncio.get_event_loop()

def get_toner(url, loop):
    # 必须将run_in_executor返回的Future对象返回,供外部收集
    return loop.run_in_executor(executor, scraper, url)

def scraper(url):
    # 原有爬取逻辑,返回对应打印机的墨粉余量百分比
    pass

def main():
    task_list = []
    for stampante in lista_totale:
        # 逐次将生成的executor任务存入列表
        task_list.append(get_toner(stampante, loop=loop))
        
    # 等待所有任务执行完成后统一收集返回结果
    lista_verificati = loop.run_until_complete(asyncio.gather(*task_list))
    print(lista_verificati)

if __name__ == "__main__":
    main()

实操注意点

  • 不要依赖asyncio.all_tasks()凑待收集的任务列表,提交任务阶段就要手动持有所有任务的引用,避免非预期的任务遗漏。
  • 线程池并发数不要设置过高,否则会触发目标打印机Web服务的访问限流,导致爬取失败。
  • Python 3.7及以上版本可直接使用asyncio.run()替代手动获取、管理事件循环的写法,减少循环生命周期管理的出错概率。

内容的提问来源于stack exchange,提问作者Gian76

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 08:36:02