如何连接到已打开的Firefox浏览器?
我看你现在遇到的问题是:代码里明明已经启动了带自动化标记的Firefox,但调用webdriver.Firefox()时一直卡着直到超时,没法顺利连接到已打开的浏览器,对吧?这大概率是因为启动Firefox和配置GeckoDriver时的端口参数没对应上,导致驱动找不到可连接的Marionette实例。
咱们来一步步修正你的代码,解决这个问题:
问题根源
你启动Firefox的命令只加了--marionette参数,但没指定具体的监听端口;可GeckoDriver的service_args里却指定了--marionette-port=2828,这时候Firefox根本没在2828端口监听,驱动自然会一直卡在连接步骤直到超时。
修正方案
1. 启动Firefox时指定监听端口
启动Firefox的命令里,要加上--marionette-port=2828(和后续驱动的端口保持一致),还要加--no-remote参数——这个参数允许同时运行多个Firefox实例,避免和你手动打开的普通Firefox进程冲突:
command = [ binary_path, '--marionette', '--marionette-port=2828', '--no-remote', ]
2. 给Firefox留启动时间
启动Firefox后,别立刻就让驱动去连接,加个1-2秒的延时,确保浏览器完全启动并开始监听端口,不然驱动可能赶在Firefox准备好之前发起连接,还是会超时:
import time # 记得导入time模块 # 启动Firefox的代码之后加这行 time.sleep(2)
3. 同步FirefoxOptions的参数
你的custom_firefox_options里也要加上--no-remote,和启动命令的参数保持一致,避免参数冲突:
custom_firefox_options = webdriver.FirefoxOptions() custom_firefox_options.add_argument('--no-remote') # 这里可以继续添加你需要的其他选项,比如禁用弹窗拦截之类的
4. 确保GeckoDriver参数正确
你原来的GeckoDriver服务配置是对的,--connect-existing参数会告诉驱动不要启动新的Firefox实例,而是连接已有的Marionette服务,只要端口和启动Firefox时的一致就行。
修正后的完整代码
import subprocess import time from selenium import webdriver from selenium.webdriver.firefox.service import FirefoxService from webdriver_manager.firefox import GeckoDriverManager def create_firefox_driver() -> webdriver.Firefox: firefox_driver = None binary_path = 'C:\\Program Files\\Mozilla Firefox\\firefox.exe' # 1. 启动带指定端口的Firefox实例 command = [ binary_path, '--marionette', '--marionette-port=2828', '--no-remote', ] subprocess.Popen(command, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # 等待Firefox完全启动 time.sleep(2) # 2. 配置Firefox选项 custom_firefox_options = webdriver.FirefoxOptions() custom_firefox_options.add_argument('--no-remote') # 可添加其他自定义选项,比如: # custom_firefox_options.add_argument('--private-window') # custom_firefox_options.set_preference('dom.disable_open_during_load', False) # 3. 配置GeckoDriver服务,连接已有的Firefox实例 executable_path = GeckoDriverManager().install() service = FirefoxService( executable_path=executable_path, service_args=['--marionette-port=2828', '--connect-existing'] ) # 4. 连接到已启动的Firefox try: firefox_driver = webdriver.Firefox(service=service, options=custom_firefox_options) print("成功连接到已打开的Firefox浏览器!") except Exception as e: print(f"连接失败:{str(e)}") raise e return firefox_driver
额外注意事项
- 运行代码前,最好关掉你手动打开的Firefox窗口,避免端口或实例冲突;
- 如果之前运行过类似代码,要检查任务管理器里有没有残留的Firefox或geckodriver进程,杀掉旧进程再重新运行,防止端口被占用。
这样改完之后,GeckoDriver就能顺利连接到你提前启动的Firefox实例,不会再卡在webdriver.Firefox()这一步啦!
备注:内容来源于stack exchange,提问作者Nishtha Sharma

