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

Ubuntu VPS上Python脚本结合Firefox与Selenium运行失败求助

Ubuntu VPS上Firefox+Selenium初始化失败:Process unexpectedly closed with status 1

问题详情

在Ubuntu VPS上运行结合Firefox与Selenium的Python脚本,执行以下pytest命令:

pytest /usr/local/bin/ciaobot/ciao.py --indirizzo "https://www.test.it" --profilo "ciao1"

测试失败,核心报错为:

selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 1

错误触发于初始化Firefox driver的代码行(/usr/local/bin/ciaobot/ciao.py:34),完整报错堆栈如下:

========================================================== test session starts ==========================================================
platform linux -- Python 3.10.12, pytest-8.0.2, pluggy-1.4.0
rootdir: /usr/local/bin/ciaobot
plugins: devtools-0.12.2, anyio-4.3.0
collected 1 item

../usr/local/bin/ciao/ciao.py F                                                                                              [100%]

=============================================================== FAILURES ================================================================
______________________________________________________________ test_fbpost ______________________________________________________________

params = {'filelista': None, 'gruppo': None, 'indirizzo': 'https://www.test.it', 'messaggio': None, ...}

    def test_fbpost(params):
      profile_path = '/root/.mozilla/firefox-esr/' + params['profilo']
      options = Options()
      options.add_argument('-profile')
      options.add_argument(profile_path)
      options.add_argument("--width=1665")
      options.add_argument("--height=1720")
      options.set_preference('permissions.default.image', 2)
      options.set_preference('layout.css.devPixelsPerPx', '0.6')

      service = Service('/usr/local/bin/geckodriver', log_path='/dev/null')
>     driver = Firefox(service=service, options=options)

/usr/local/bin/ciaobot/ciao.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.10/dist-packages/selenium/webdriver/firefox/webdriver.py:69: in __init__
    super().__init__(command_executor=executor, options=options)
/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py:208: in __init__
    self.start_session(capabilities)
/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py:292: in start_session
    response = self.execute(Command.NEW_SESSION, caps)["value"]
/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/webdriver.py:347: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f1232ca8490>
response = {'status': 500, 'value': '{"value":{"error":"unknown error","message":"Process unexpectedly closed with status 1","stacktrace":""}}'}

    def check_response(self, response: Dict[str, Any]) -> None:
        """Checks that a JSON response from the WebDriver does not have an
        error.

        :Args:
         - response - The JSON response from the WebDriver server as a dictionary
           object.

        :Raises: If the response contains an error message.
        """
        status = response.get("status", None)
        if not status or status == ErrorCode.SUCCESS:
            return
        value = None
        message = response.get("message", "")
        screen: str = response.get("screen", "")
        stacktrace = None
        if isinstance(status, int):
            value_json = response.get("value", None)
            if value_json and isinstance(value_json, str):
                import json

                try:
                    value = json.loads(value_json)
                    if len(value) == 1:
                        value = value["value"]
                    status = value.get("error", None)
                    if not status:
                        status = value.get("status", ErrorCode.UNKNOWN_ERROR)
                        message = value.get("value") or value.get("message")
                        if not isinstance(message, str):
                            value = message
                            message = message.get("message")
                    else:
                        message = value.get("message", None)
                except ValueError:
                    pass

        exception_class: Type[WebDriverException]
        e = ErrorCode()
        error_codes = [item for item in dir(e) if not item.startswith("__")]
        for error_code in error_codes:
            error_info = getattr(ErrorCode, error_code)
            if isinstance(error_info, list) and status in error_info:
                exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
                break
        else:
            exception_class = WebDriverException

        if not value:
            value = response["value"]
        if isinstance(value, str):
            raise exception_class(value)
        if message == "" and "message" in value:
            message = value["message"]

        screen = None  # type: ignore[assignment]
        if "screen" in value:
            screen = value["screen"]

        stacktrace = None
        st_value = value.get("stackTrace") or value.get("stacktrace")
        if st_value:
            if isinstance(st_value, str):
                stacktrace = st_value.split("\n")
            else:
                stacktrace = []
                try:
                    for frame in st_value:
                        line = frame.get("lineNumber", "")
                        file = frame.get("fileName", "<anonymous>")
                        if line:
                            file = f"{file}:{line}"
                        meth = frame.get("methodName", "<anonymous>")
                        if "className" in frame:
                            meth = f"{frame['className']}.{meth}"
                        msg = "    at %s (%s)"
                        msg = msg % (meth, file)
                        stacktrace.append(msg)
                except TypeError:
                    pass
        if exception_class == UnexpectedAlertPresentException:
            alert_text = None
            if "data" in value:
                alert_text = value["data"].get("text")
            elif "alert" in value:
                alert_text = value["alert"].get("text")
            raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
>       raise exception_class(message, screen, stacktrace)
E       selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 1

/usr/local/lib/python3.10/dist-packages/selenium/webdriver/remote/errorhandler.py:229: WebDriverException
======================================================== short test summary info ========================================================
FAILED ../usr/local/bin/ciaobot/ciao.py::test_fbpost - selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 1
========================================================== 1 failed in 10.21s ===========================================================

解决步骤

1. 检查Firefox配置文件有效性与权限

  • 确认配置文件路径/root/.mozilla/firefox-esr/ciao1存在,且root用户拥有读写权限:
    ls -ld /root/.mozilla/firefox-esr/ciao1
    
  • 手动启动Firefox加载该配置,验证是否能正常运行:
    firefox-esr -profile /root/.mozilla/firefox-esr/ciao1
    
    若启动失败,删除损坏的配置文件并重新创建,或更换其他可用配置文件。

2. 确保Geckodriver与Firefox版本兼容

  • 查看当前Firefox ESR版本:
    firefox-esr --version
    
  • 查看Geckodriver版本:
    geckodriver --version
    
  • 两者版本需匹配(例如Geckodriver 0.33.x对应Firefox 115+ ESR),版本不匹配则下载对应版本替换/usr/local/bin/geckodriver,并赋予执行权限:
    chmod +x /usr/local/bin/geckodriver
    

3. 适配VPS无桌面环境

VPS通常无图形界面,需添加headless模式参数到Selenium配置中:

options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

同时安装Firefox运行所需的依赖库:

apt update && apt install -y libgtk-3-0 libdbus-glib-1-2 libxt6

4. 开启Geckodriver日志排查细节

将代码中log_path='/dev/null'改为实际日志路径,比如:

service = Service('/usr/local/bin/geckodriver', log_path='/var/log/geckodriver.log')

运行测试后查看日志内容,可获取Firefox启动失败的具体原因,进一步定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:10:55