You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Selenium如何同时运行Chrome和Firefox两款webdriver

根因说明

你遇到的stale element reference错误和Selenium的线程安全无关,本质是并发执行时系统资源调度导致driver的页面加载/渲染速度和单跑时不一致,元素操作刚好触发了DOM更新的间隙,加上定位逻辑没有做异常重试导致的。

修复方案

1. 修复元素定位逻辑(必做)

  • 所有元素操作前必须加显式等待,不要依赖隐式等待或硬编码等待时间,同时封装重试逻辑兼容stale异常,参考代码:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException

def get_element(driver, locator, timeout=10, retry=3):
    for _ in range(retry):
        try:
            return WebDriverWait(driver, timeout).until(
                EC.element_to_be_clickable(locator)
            )
        except StaleElementReferenceException:
            continue
    raise Exception(f"重试{retry}次后仍无法定位元素: {locator}")
  • 绝对不要跨driver实例共享任何定位到的WebElement对象,每个driver的元素只能在对应执行流程内使用,禁止跨线程传递。
  • driver的初始化、执行、销毁全放在check_url函数内部实现,每个线程完全独立持有自己的driver实例,彻底隔离避免变量共享,参考check_url结构:
from selenium import webdriver

def check_url(url, driver_path, driver_type):
    # 线程内部独立初始化driver
    if driver_type == "chrome":
        options = webdriver.ChromeOptions()
        # 补充你的无头/其他配置项
        driver = webdriver.Chrome(executable_path=driver_path, options=options)
    elif driver_type == "firefox":
        options = webdriver.FirefoxOptions()
        # 补充你的无头/其他配置项
        driver = webdriver.Firefox(executable_path=driver_path, options=options)
    try:
        driver.get(url)
        # 业务逻辑:所有元素操作都调用上面封装的get_element方法
        res = "业务执行结果"
        return res
    finally:
        # 执行结束销毁driver释放资源
        driver.quit()

2. 调整并发调用逻辑

  • 不要提前初始化driver实例,调用时仅传入driver的配置参数即可,参考调整后的调用代码:
import concurrent.futures
import requests

# 仅存储driver配置,不提前创建实例
driver_configs = [
    {"type": "chrome", "path": "你的chromedriver.exe路径"},
    {"type": "firefox", "path": "你的geckodriver.exe路径"}
]
target_url = "你的目标测试URL"

with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
    futures = []
    for config in driver_configs:
        futures.append(executor.submit(
            check_url,
            url=target_url,
            driver_path=config["path"],
            driver_type=config["type"]
        ))
    for future in concurrent.futures.as_completed(futures):
        try:
            print(future.result())
        except requests.ConnectTimeout:
            print("ConnectTimeout")
        except Exception as e:
            print(f"执行异常: {str(e)}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:51:00