Python Multiprocessing结合Selenium能否在同一驱动下多任务并行?
关于多进程共享Selenium驱动实例的问题解答
问题原因分析
你当前代码出现多窗口的核心原因如下:
- Python多进程具备独立内存空间,主进程中初始化的
driver实例无法直接共享给子进程,子进程拿到的是序列化后重新生成的副本,每个副本都会启动新的Chrome窗口,加上主进程初始化时启动的窗口,最终就会出现3个独立窗口。 - Selenium原生WebDriver实例本身不支持跨进程共享,属于进程绑定的资源。
该需求无法直接通过标准multiprocessing实现,可通过以下两种可行方案达成预期效果。
可行实现方案
方案1:改用多线程实现(推荐,实现成本最低)
线程共享所属进程的全部内存资源,可以直接共用同一个driver实例,注意需要加锁避免多线程同时操作驱动导致的并发冲突。
代码示例:
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from threading import Thread, Lock from selenium import webdriver import time options = webdriver.ChromeOptions() options.add_argument("start-maximized") options.add_argument("disable-infobars") options.add_argument("--disable-extensions") options.add_experimental_option('useAutomationExtension', False) options.add_argument('--disable-blink-features=AutomationControlled') options.add_experimental_option("excludeSwitches" , ["enable-automation"]) driver = webdriver.Chrome(options=options, executable_path = './chromedriver') # 初始化线程锁,避免并发操作冲突 driver_lock = Lock() def func1(): with driver_lock: driver.get('https://test.com') # 此处可添加事件监听逻辑,触发后再启动func2对应逻辑 def func2(): # 可添加等待func1触发信号的逻辑,此处简化直接执行 time.sleep(2) with driver_lock: # 在同一个驱动实例上执行操作,新开标签页避免覆盖原页面 driver.execute_script("window.open('');") driver.switch_to.window(driver.window_handles[-1]) driver.get('https://test2.com') if __name__ == '__main__': t1 = Thread(target=func1) t2 = Thread(target=func2) t1.start() t2.start() t1.join() t2.join() # 执行完毕后统一关闭驱动 driver.quit()
方案2:Chrome远程调试模式+多进程(适合必须用多进程的场景)
先手动启动绑定了调试端口的Chrome实例,所有进程都通过调试端口连接同一个浏览器,避免重复启动新窗口。
操作步骤:
- 命令行启动Chrome(路径替换为你本地Chrome的实际路径):
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="自定义临时Chrome数据目录路径" - 所有进程通过调试端口连接同一个Chrome实例,代码示例:
from multiprocessing import Process from selenium import webdriver from selenium.webdriver.chrome.options import Options def get_shared_driver(): options = Options() options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") driver = webdriver.Chrome(options=options, executable_path='./chromedriver') return driver def func1(): driver = get_shared_driver() driver.get('https://test.com') def func2(): driver = get_shared_driver() driver.execute_script("window.open('');") driver.switch_to.window(driver.window_handles[-1]) driver.get('https://test2.com') if __name__ == '__main__': p1 = Process(target=func1) p2 = Process(target=func2) p1.start() p2.start() p1.join() p2.join()
注意事项
- Selenium本身不是线程安全的,不管用多线程还是多进程,同一时间只能有一个逻辑操作驱动实例,必须加锁避免并发操作导致的DOM异常、元素定位失败等问题。
- 如果需要两个逻辑同时监听页面不同事件,可以用异步IO方案(比如
asyncio+ 异步Selenium封装)实现更高的执行效率。
内容的提问来源于stack exchange,提问作者jenusi1971
相关产品推荐
相关产品推荐

