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

如何让Selenium管控的Firefox实例在脚本终止后保持运行并可重连

实现Selenium复用Firefox实例的方案

核心思路

  • 首次执行脚本时,通过Selenium启动带有Marionette调试端口的Firefox实例,并配置实例在脚本终止后保留运行
  • 后续执行脚本时,先检测指定端口是否有运行的Firefox实例,若存在则直接连接,无需重新启动
  • 全程基于Selenium官方API实现,无需使用popen子进程

关键配置要点

  • 指定Firefox二进制路径:由于系统默认未安装Firefox,需明确指向~/.cache/firefox中的Firefox可执行文件(Windows下为.exe,Linux/macOS下为对应可执行文件)
  • 开启Marionette调试端口:添加--marionette-port=2828参数(可自定义端口),允许Selenium后续连接实例
  • 保留浏览器实例:设置options.detach = True,避免脚本终止时Firefox被自动关闭
  • 端口可用性检测:通过尝试建立socket连接,判断目标端口是否已有Firefox实例在监听

修改后的完整代码

from selenium.webdriver.firefox.options import Options
from selenium import webdriver
import socket

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class Browser:
    # 自定义配置项
    MARIONETTE_PORT = 2828
    # 替换为~/.cache/firefox中的Firefox可执行文件路径
    FIREFOX_BINARY_PATH = "~/.cache/firefox/firefox"  # Linux/macOS示例,Windows请改为类似"C:/Users/xxx/AppData/Local/Temp/firefox.exe"
    PROFILE_PATH = "C:/firefox/profile/"

    firefox_options = Options()
    firefox_options.add_argument("-profile")
    firefox_options.add_argument(PROFILE_PATH)
    # 开启Marionette端口
    firefox_options.add_argument(f"--marionette-port={MARIONETTE_PORT}")
    # 设置脚本终止后保留浏览器实例
    firefox_options.detach = True
    # 指定Firefox二进制文件路径
    firefox_options.binary_location = FIREFOX_BINARY_PATH

    driver = None
    wait = None
    EC = EC
    By = By
    Keys = Keys
    ActionChains = ActionChains
    ActionBuilder = ActionBuilder

    @staticmethod
    def _is_port_in_use(port):
        """检测指定端口是否被占用"""
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            return s.connect_ex(('localhost', port)) == 0

    def __init__(self):
        try:
            if self._is_port_in_use(self.MARIONETTE_PORT):
                # 端口已占用,连接已运行的Firefox实例
                self.driver = webdriver.Firefox.connect(f"http://localhost:{self.MARIONETTE_PORT}")
            else:
                # 端口未占用,启动新的Firefox实例
                self.driver = webdriver.Firefox(options=self.firefox_options)
            
            self.wait = WebDriverWait(self.driver, timeout=15, poll_frequency=.2)
        except Exception as e:
            raise ValueError(f"浏览器连接或启动失败: {str(e)}")

代码说明

  1. 端口检测函数:_is_port_in_use通过socket连接尝试,判断目标端口是否有Firefox实例在监听
  2. 实例分支逻辑:
    • 若端口已被占用,调用webdriver.Firefox.connect()连接已运行的实例
    • 若端口未被占用,调用webdriver.Firefox()启动新实例,同时通过配置确保实例在脚本退出后保留
  3. 路径配置:需根据实际系统环境修改FIREFOX_BINARY_PATH和PROFILE_PATH,确保路径正确

内容的提问来源于stack exchange,提问作者Neo Yion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:27:41