【问题标题】:Stop concurrent.futures if a condition is met and then execute again after the task is done如果满足条件,则停止 concurrent.futures,然后在任务完成后再次执行
【发布时间】:2021-09-29 03:59:13
【问题描述】:

我正在使用 python 请求库从网站 (https://www.nseindia.com/) 获取 JSON 数据。该网站仅在提供正确 cookie 的情况下提供数据。所以我使用 selenium webdriver 来获取 cookie,然后获取 850 种不同股票的数据。

现在,我的代码是这样的,如果 cookie 错误,那么 selenium 应该再次打开并获取新的 cookie 值。但问题是,当我使用 concurrent.futures 时,任务非常快(由于异步性),它会为每个符号打开新的驱动程序,直到找不到新的 cookie。我的代码如下:

--初步获取cookies


cookie_dict = get_cookies()

for cookie in cookie_dict:
        if cookie == "bm_sv" or cookie == "nsit" or cookie == "nseappid":
            session.cookies.set(cookie,cookie_dict[cookie])

--线程池执行器中使用该函数

def final(u):
    try:
        data = session.get(u,headers = headers).json()
        print(data['data'][0]['CH_SYMBOL'])
        list_done.append(data['data'][0]['CH_SYMBOL'])
        
    except:
        print("Error")
        cookie_dict = get_cookies()

        for cookie in cookie_dict:
            if cookie == "bm_sv" or cookie == "nsit" or cookie == "nseappid":
                session.cookies.set(cookie,cookie_dict[cookie])
        data = session.get(u,headers = headers).json()
        print(data['data'][0]['CH_SYMBOL'])
        list_done.append(data['data'][0]['CH_SYMBOL'])

如您所见,如果遇到异常,它应该获取新的 cookie。但正如我之前提到的,其他股票的期货将继续运行,并且会遇到例外情况,直到找不到新的 cookie。

with concurrent.futures.ThreadPoolExecutor(max_workers = 5) as executor:
    executor.map(final,urls)

有没有一种方法可以更改我的代码,或者一些由 futures 内置的设施,这样我就可以停止它,直到我没有获得新的 cookie 并只有在附加了新的 cookie 时才继续运行?

【问题讨论】:

    标签: python json python-requests threadpoolexecutor concurrent.futures


    【解决方案1】:

    您可以使用concurrent.futureswait() 方法来监视第一个异常。首先,您必须将final 更改为投掷。你不应该追加到这个函数内的共享列表,你应该返回值:

    def final(u):
        data = session.get(u,headers = headers).json()
        print(data['data'][0]['CH_SYMBOL'])
        return data['data'][0]['CH_SYMBOL']
    

    其次,您提交工作和存储期货,而不是使用.map()

    from concurrent.futures import ThreadPoolExecutor
    
    with ThreadPoolExecutor() as executor:
        futures = [executor.submit(final, u) for u in urls]
    

    然后你使用wait() 等待异常发生。在这里,要么有一个异常,你在继续之前处理它,没有错误,你解开期货:

    from concurrent.futures import wait, FIRST_EXCEPTION
    
    completed, not_done = wait(futures, return_when=FIRST_EXCEPTION)
    
    if not_done:
      # An exception occurred before all futures completed,
      # handle it here.
    
    # Here, handle the results of the futures,
    # `completed` contains both finished and failed futures,
    # `not_done` contains pending futures.
    

    请注意,在打开包装之前,您应该检查每个未来是否成功或失败,并且您应该重新提交失败的未来。此外,wait() 函数不会取消挂起的期货,因此not_done 期货仍在进行中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 2013-08-08
      • 2018-10-14
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多