Windows环境下Python3.9+Selenium+geckodriver 0.29.1触发ConnectionRefusedError[WinError10061]问题排查
这个错误的核心原因是:当你按下Ctrl+C触发KeyboardInterrupt中断无限循环时,Windows系统的信号处理机制可能已经连带终止了关联的geckodriver进程,或者geckodriver因为检测到Python主进程的中断信号,主动退出了服务。
当你的代码执行到finally块之后,再调用driver.get()或者driver.quit()时,Python端的Selenium驱动对象试图连接本地的geckodriver服务,但此时该服务已经不存在了,所以会抛出ConnectionRefusedError [WinError 10061]——因为目标服务(geckodriver)已经关闭,自然拒绝了连接请求。
另外,你的代码逻辑里,driver.get()是写在finally块之后的,这本身就有问题:即使geckodriver没被终止,无限循环被中断后,你应该先完成浏览器的清理操作(比如driver.quit()),而不是继续尝试访问网页。
调整代码逻辑,确保在捕获中断信号后,立即在finally块内执行driver.quit(),同时避免在finally之后再调用任何driver的方法。这里提供两种可行的写法:
写法一:优化finally块逻辑
把driver的清理操作放在finally块里,确保无论是否触发中断,都能优先关闭浏览器和geckodriver:
from selenium import webdriver firefox_profile = webdriver.FirefoxProfile() driver = webdriver.Firefox(firefox_profile=firefox_profile) print("Going into loop") try: while True: pass except KeyboardInterrupt: print("Caught exception") finally: print("Finally block: closing driver") driver.quit() # 在这里执行退出操作,确保geckodriver被正常关闭 print("Got out of loop")
写法二:使用signal模块捕获中断信号(更可靠)
在Windows下,有时候KeyboardInterrupt的处理可能不够及时,你可以用signal模块来捕获SIGINT信号,确保在收到中断信号时先关闭driver:
from selenium import webdriver import signal import sys def signal_handler(sig, frame): print("\nCaught interrupt, closing driver") driver.quit() sys.exit(0) # 注册信号处理器 signal.signal(signal.SIGINT, signal_handler) firefox_profile = webdriver.FirefoxProfile() driver = webdriver.Firefox(firefox_profile=firefox_profile) print("Going into loop") while True: pass
- 永远要确保在使用Selenium完成操作后,调用
driver.quit()(而不是driver.close()),因为quit()会彻底终止geckodriver进程,而close()只是关闭当前标签页,进程仍然存在。 - 在Windows环境下,Python的信号处理和Unix系统略有不同,使用
signal模块可以更稳定地捕获中断信号,避免geckodriver被意外终止。
内容的提问来源于stack exchange,提问作者Maarten Meijer

