如何编写Dockerfile运行非无头模式的Selenium GUI程序?
问题
我开发了一款Python程序,从数据库获取信息后访问网站执行操作,使用Selenium实现,要求以非无头(non-headless)模式运行。简化后的程序代码如下:
import time from selenium import webdriver from selenium_stealth import stealth options = webdriver.ChromeOptions() chrome_driver_path = "chromedriver.exe" options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) driver = webdriver.Chrome(options=options) stealth(driver, languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) driver.get('https://google.com') time.sleep(10) driver.close() driver.quit() print('Test done')
我尝试了两个Dockerfile:
- 方案一运行后报错,错误信息:
2023-07-26 12:39:59 Traceback (most recent call last): 2023-07-26 12:39:59 File "/app/main.py", line 11, in <module> 2023-07-26 12:39:59 driver = webdriver.Chrome(options=options) 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/chrome/webdriver.py", line 49, in __init__ 2023-07-26 12:39:59 super().__init__( 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/chromium/webdriver.py", line 54, in __init__ 2023-07-26 12:39:59 super().__init__( 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 206, in __init__ 2023-07-26 12:39:59 self.start_session(capabilities) 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 291, in start_session 2023-07-26 12:39:59 response = self.execute(Command.NEW_SESSION, caps)["value"] 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 346, in execute 2023-07-26 12:39:59 self.error_handler.check_response(response) 2023-07-26 12:39:59 File "/usr/local/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response 2023-07-26 12:39:59 raise exception_class(message, screen, stacktrace) 2023-07-26 12:39:59 selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally. 2023-07-26 12:39:59 (unknown error: DevToolsActivePort file doesn't exist) 2023-07-26 12:39:59 (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.) 2023-07-26 12:39:59 Stacktrace: 2023-07-26 12:39:59 #0 0x55cb45ef94e3 <unknown> 2023-07-26 12:39:59 #1 0x55cb45c28c76 <unknown> 2023-07-26 12:39:59 #2 0x55cb45c51d78 <unknown> 2023-07-26 12:39:59 #3 0x55cb45c4e029 <unknown> 2023-07-26 12:39:59 #4 0x55cb45c8cccc <unknown> 2023-07-26 12:39:59 #5 0x55cb45c8c47f <unknown> 2023-07-26 12:39:59 #6 0x55cb45c83de3 <unknown> 2023-07-26 12:39:59 #7 0x55cb45c592dd <unknown> 2023-07-26 12:39:59 #8 0x55cb45c5a34e <unknown> 2023-07-26 12:39:59 #9 0x55cb45eb93e4 <unknown> 2023-07-26 12:39:59 #10 0x55cb45ebd3d7 <unknown> 2023-07-26 12:39:59 #11 0x55cb45ec7b20 <unknown> 2023-07-26 12:39:59 #12 0x55cb45ebe023 <unknown> 2023-07-26 12:39:59 #13 0x55cb45e8c1aa <unknown> 2023-07-26 12:39:59 #14 0x55cb45ee26b8 <unknown> 2023-07-26 12:39:59 #15 0x55cb45ee2847 <unknown> 2023-07-26 12:39:59 #16 0x55cb45ef2243 <unknown> 2023-07-26 12:39:59 #17 0x7f6861704fd4 <unknown> 2023-07-26 12:39:59
- 方案二运行后无任何响应。
请问应该编写什么样的Dockerfile才能正常运行该程序?
解决方案
第一步:修改Python代码
原代码存在Windows环境路径依赖、缺少Linux启动参数的问题,修改后代码如下:
import time from selenium import webdriver from selenium_stealth import stealth from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager options = webdriver.ChromeOptions() # 添加Linux环境下Chrome必需的启动参数 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--disable-gpu") # 非无头模式需指定窗口大小,配合虚拟显示使用 options.add_argument("--window-size=1920,1080") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) # 用webdriver-manager自动匹配ChromeDriver版本,无需手动指定路径 driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options) stealth(driver, languages=["en-US", "en"], vendor="Google Inc.", platform="Linux x86_64", # 改为Linux平台,匹配Docker环境 webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) driver.get('https://google.com') time.sleep(10) driver.quit() print('Test done')
第二步:编写Dockerfile
Docker容器无原生图形界面,需安装Chrome、虚拟显示服务(Xvfb)及依赖库,Dockerfile内容:
# 基于Python 3.9 slim镜像构建 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 安装系统依赖:Chrome浏览器、Xvfb虚拟显示、图形依赖库 RUN apt-get update && apt-get install -y --no-install-recommends \ google-chrome-stable \ xvfb \ libxss1 \ libappindicator1 \ libasound2 \ libnss3 \ && rm -rf /var/lib/apt/lists/* # 复制并安装Python依赖(先复制requirements.txt可利用Docker缓存) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制程序代码 COPY main.py . # 启动命令:先启动Xvfb虚拟显示,再执行Python程序 CMD ["sh", "-c", "Xvfb :99 -screen 0 1920x1080x24 & export DISPLAY=:99 && python main.py"]
第三步:创建requirements.txt
列出所有Python依赖包:
selenium selenium-stealth webdriver-manager
关键说明
- Xvfb的作用:Docker容器无图形界面,Xvfb提供虚拟X服务器,让Chrome能在非无头模式下渲染界面。
- Chrome启动参数:
--no-sandbox关闭沙箱(Docker环境无需沙箱),--disable-dev-shm-usage避免临时空间不足导致Chrome崩溃。 - webdriver-manager:自动下载匹配当前Chrome版本的ChromeDriver,解决版本兼容问题。
内容的提问来源于stack exchange,提问作者Nero
相关产品推荐
相关产品推荐

