如何终止以multiprocessing.Process运行的Selenium并关闭窗口?
问题:Selenium多进程终止后Chrome窗口残留(macOS Ventura 13.0.1)
在macOS Ventura 13.0.1系统中,运行以下多进程调用Selenium的代码时,即使终止了子进程,Chrome窗口依然保持打开状态:
from multiprocessing import Process from selenium.webdriver import Chrome def func(): driver = Chrome() driver.get('https://google.com') if __name__ == '__main__': p = Process(target=func) p.daemon = True p.start() p.join(timeout=1) if p.is_alive(): p.terminate()
当前临时解决方法:
os.system("ps aux | grep Google | awk ' { print $2 } ' | xargs kill -9")
窗口未关闭的原因
p.terminate()仅终止了Python子进程,但Selenium启动的Chrome浏览器是独立的系统进程,和Python子进程属于同级或不同进程组(macOS的进程管理机制导致),不会随Python进程终止而自动关闭。- 代码中没有显式调用
driver.quit()——这个方法才是Selenium用来彻底关闭浏览器及相关进程的核心逻辑,而强制终止子进程会直接中断代码执行,根本没机会触发这个操作。 daemon=True只是让主进程退出时自动终止守护子进程,但同样无法关联关闭Chrome的独立进程。
解决方法
方法1:显式保证浏览器关闭(推荐)
用try/finally块确保无论子进程正常结束还是被终止前,只要初始化了driver就执行关闭操作:
from multiprocessing import Process from selenium.webdriver import Chrome def func(): driver = None try: driver = Chrome() driver.get('https://google.com') finally: if driver: driver.quit() # 确保浏览器进程被彻底清理 if __name__ == '__main__': p = Process(target=func) p.start() p.join(timeout=1) if p.is_alive(): p.terminate() p.join() # 等待进程完全终止
方法2:精准终止关联的Chrome进程
如果无法修改子进程逻辑,可以通过父进程ID过滤,只杀掉当前子进程启动的Chrome窗口,避免误杀其他Chrome实例:
import os from multiprocessing import Process from selenium.webdriver import Chrome def func(): driver = Chrome() driver.get('https://google.com') if __name__ == '__main__': p = Process(target=func) p.start() p.join(timeout=1) if p.is_alive(): p.terminate() p.join() # 通过父进程ID过滤,只终止当前子进程启动的Chrome os.system(f"ps aux | grep 'Chrome' | grep -v grep | awk '{{if ($3 == {p.pid}) print $2}}' | xargs kill -9")
方法3:使用无头模式(无需可视化窗口时)
如果不需要显示浏览器窗口,直接启动无头模式,从根源避免窗口残留问题:
from multiprocessing import Process from selenium.webdriver import Chrome from selenium.webdriver.chrome.options import Options def func(): options = Options() options.add_argument('--headless=new') # 新版无头模式,兼容性更好 driver = Chrome(options=options) driver.get('https://google.com') driver.quit() if __name__ == '__main__': p = Process(target=func) p.start() p.join(timeout=1) if p.is_alive(): p.terminate()
内容的提问来源于stack exchange,提问作者watch-this
相关产品推荐
相关产品推荐

