Python concurrent.futures并发请求遇Cookie失效如何暂停后恢复执行
解决方案
concurrent.futures没有内置的全局暂停任务功能,你可以通过Python标准库的线程同步原语(锁+条件变量)实现需求,核心逻辑是加全局状态标记避免重复刷新Cookie,所有线程发现正在刷新Cookie时自动等待,刷新完成后再继续执行。
第一步:新增全局同步变量
import threading import requests from concurrent.futures import ThreadPoolExecutor # 全局状态标记:是否正在刷新Cookie cookie_refreshing = False # 条件变量,控制Cookie刷新的同步逻辑 cookie_lock = threading.Condition() session = requests.Session() list_done = [] headers = {} # 此处填写你自己的请求头定义
第二步:修改任务函数的异常处理逻辑
def final(u): # 最多重试2次,避免非Cookie失效类异常导致无限循环 retry_count = 2 while retry_count > 0: try: data = session.get(u, headers=headers).json() symbol = data['data'][0]['CH_SYMBOL'] print(symbol) list_done.append(symbol) return except Exception as e: retry_count -= 1 # 拿锁判断Cookie状态 with cookie_lock: # 如果已经有线程在刷新Cookie,等待刷新完成通知 while cookie_refreshing: cookie_lock.wait() # 如果是第一个触发异常的线程,执行Cookie刷新 if not cookie_refreshing: cookie_refreshing = True # 先释放锁再执行刷新,避免刷新过程中其他线程被阻塞在拿锁步骤 cookie_lock.release() try: print("正在更新Cookie") cookie_dict = get_cookies() # 重新拿锁更新Cookie和状态 cookie_lock.acquire() for cookie in ["bm_sv", "nsit", "nseappid"]: if cookie in cookie_dict: session.cookies.set(cookie, cookie_dict[cookie]) finally: cookie_refreshing = False # 通知所有等待的线程Cookie已更新 cookie_lock.notify_all() # 刷新完成后进入下一轮循环重试请求
第三步:原有线程池调用逻辑无需修改
# 初始化Cookie cookie_dict = get_cookies() for cookie in ["bm_sv", "nsit", "nseappid"]: if cookie in cookie_dict: session.cookies.set(cookie, cookie_dict[cookie]) # 执行所有股票数据拉取任务 urls = [] # 此处填写你自己的850个股票请求地址 with ThreadPoolExecutor(max_workers = 5) as executor: executor.map(final, urls)
注意事项
- 上述逻辑可以保证同一时间只会有一个线程启动Selenium刷新Cookie,其他线程会自动等待Cookie更新完成后再重试,不会出现重复启动Driver的问题。
- 如果要进一步优化,可以在
get_cookies里加Driver复用逻辑,不用每次刷新Cookie都重启Selenium进程,大幅提升Cookie更新效率。
内容的提问来源于stack exchange,提问作者Facts Theory Story
相关产品推荐
相关产品推荐

