解决Python-Selenium连接Docker化Selenium服务器时的连接重置问题
解决Python-Selenium连接Docker化Selenium服务器时的连接重置问题
我之前也碰到过一模一样的问题,咱们一步步来排查解决:
核心原因分析
你遇到的ConnectionResetError大概率是两个问题导致的:一是容器启动后Selenium服务还没完全就绪,脚本就立刻发起连接;二是Firefox没有配置为headless模式,在无桌面环境的服务器上无法正常启动。
具体解决方案
1. 等待Selenium服务就绪再连接
Docker容器启动后,里面的Selenium服务需要几秒时间初始化,直接连接肯定会失败。我们可以添加一个等待逻辑,循环检查服务状态,直到它就绪:
首先需要安装requests库(如果没装的话):
pip install requests
然后在启动容器后加入等待代码:
import time import requests # 启动容器的代码保持不变... # 等待Selenium服务就绪 max_wait = 30 # 最长等待30秒 start_time = time.time() service_ready = False while time.time() - start_time < max_wait: try: res = requests.get("http://127.0.0.1:4444/wd/hub/status") if res.status_code == 200 and res.json()["value"]["ready"]: service_ready = True print("Selenium服务已就绪") break except requests.exceptions.ConnectionError: # 服务还没起来,忽略错误继续等 pass time.sleep(1) if not service_ready: print("超时:Selenium服务未在规定时间内启动") # 可以选择停止容器并退出 firefox.stop() exit(1)
2. 配置Firefox为Headless模式
你在服务器上运行,必须让Firefox以headless模式启动,而且你设置了SE_START_XVFB=false(关闭了容器内的X服务器),这时候Firefox如果不启用headless根本无法启动。修改你的FirefoxOptions:
options = webdriver.FirefoxOptions() options.add_argument("--headless") options.add_argument("--no-sandbox") # 服务器环境下必备,绕过安全沙箱 options.add_argument("--disable-dev-shm-usage") # 解决服务器上/dev/shm空间不足的问题
3. 优化容器环境变量(可选)
如果你不确定SE_START_XVFB=false的作用,其实可以保留默认值SE_START_XVFB=true,让容器自己管理X虚拟桌面,这样Firefox即使不手动设置headless也能在容器内运行(不过服务器环境还是建议启用headless更节省资源)。
修改后的完整脚本
import docker from selenium import webdriver import time import requests client = docker.from_env() # 拉取镜像 client.images.pull("selenium/standalone-firefox:135.0.1-geckodriver-0.36.0-20250303") # 启动容器 firefox = client.containers.run( "selenium/standalone-firefox:135.0.1-geckodriver-0.36.0-20250303", detach=True, name="firefox", ports={4444: 4444, 7900: 7900}, shm_size="2G", environment=[ "SE_START_XVFB=false", "SE_SCREEN_WIDTH=1200", "SE_SCREEN_HEIGHT=900" ] ) print("当前运行的容器:", client.containers.list()) # 等待Selenium服务就绪 max_wait = 30 start_time = time.time() service_ready = False while time.time() - start_time < max_wait: try: res = requests.get("http://127.0.0.1:4444/wd/hub/status") if res.status_code == 200 and res.json()["value"]["ready"]: service_ready = True print("Selenium服务已就绪") break except requests.exceptions.ConnectionError: pass time.sleep(1) if not service_ready: print("超时:Selenium服务未启动") firefox.stop() exit(1) try: # 配置Firefox选项 options = webdriver.FirefoxOptions() options.add_argument("--headless") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") driver = webdriver.Remote( command_executor="http://127.0.0.1:4444/wd/hub", options=options ) driver.get("http://www.python.org") print("成功访问Python官网,页面标题:", driver.title) except Exception as e: print("发生异常:", e) finally: # 记得关闭driver和容器(如果需要的话) if 'driver' in locals(): driver.quit() # 停止并删除容器(可选,根据你的需求决定是否保留容器) firefox.stop() firefox.remove()
额外提示
- 运行脚本时确保当前用户有Docker权限,或者用
sudo运行(不过更推荐配置Docker用户组)。 - 如果还是有问题,可以查看容器日志,看看Firefox启动时有没有报错:
docker logs firefox
备注:内容来源于stack exchange,提问作者GNUser
相关产品推荐
相关产品推荐

