Docker容器中Selenium ChromeDriver崩溃(会话因页面崩溃被删)求助
解决Docker中Selenium Chrome页面崩溃问题
问题现象
服务器本地运行Selenium脚本可正常工作,但在Docker容器中执行到driver.find_element(By.NAME, "OK").send_keys(Keys.RETURN)时偶尔崩溃,报错提示session deleted because of page crash。
脚本代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import os try: use_service = True path_driver = os.getcwd() + "/drivers/chromedriver" options = webdriver.ChromeOptions() options.add_argument("--headless") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") if use_service: print("---> use Service()") from selenium.webdriver.chrome.service import Service service = Service(path_driver) driver = webdriver.Chrome(service=service, options=options) else: driver = webdriver.Chrome(path_driver,options=options) driver.get(my_url) driver.find_element(By.ID, "login").send_keys("bar") driver.find_element(By.ID, "pass").send_keys("foo") driver.find_element(By.NAME, "OK").send_keys(Keys.RETURN) urls = { "04": "https://xxx.xx/xxx/xxx","05": "https://xxx.xx/xxx/xxx",} for dept, url in urls.items(): driver.get(url) print(len(driver.page_source)) driver.close() driver.quit() except Exception as e: print("ERROR ", str(e))
报错信息
---> use Service() ERROR Message: unknown error: session deleted because of page crash from unknown error: cannot determine loading status from tab crashed (Session info: headless chrome=111.0.5563.64) Stacktrace: #0 0x556474bfed93 <unknown> #1 0x5564749cd15d <unknown> #2 0x5564749b908c <unknown> #3 0x5564749b8531 <unknown> #4 0x5564749b75bb <unknown> #5 0x5564749b7404 <unknown> #6 0x5564749b5ee2 <unknown> #7 0x5564749b6682 <unknown> #8 0x5564749c3b4f <unknown> #9 0x5564749c47a2 <unknown> #10 0x5564749d4ba0 <unknown> #11 0x5564749d8e40 <unknown> #12 0x5564749b6b43 <unknown> #13 0x5564749d47dc <unknown> #14 0x556474a4583a <unknown> #15 0x556474a2d353 <unknown> #16 0x5564749fce40 <unknown> #17 0x5564749fe038 <unknown> #18 0x556474c528be <unknown> #19 0x556474c568f0 <unknown> #20 0x556474c36f90 <unknown> #21 0x556474c57b7d <unknown> #22 0x556474c28578 <unknown> #23 0x556474c7c348 <unknown> #24 0x556474c7c4d6 <unknown> #25 0x556474c96341 <unknown> #26 0x7f92ba72ffa3 start_thread
环境信息
- Docker容器系统:Linux 40b5ec9c18f9 5.15.0-58-generic #64-Ubuntu SMP Thu Jan 5 11:43:13 UTC 2023 x86_64 GNU/Linux
- 宿主机系统:Linux valabre-prod23 5.15.0-58-generic #64-Ubuntu SMP Thu Jan 5 11:43:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
- Google Chrome版本:111.0.5563.64
- ChromeDriver版本:110.0.5481.77
解决方案
1. 对齐Chrome与ChromeDriver版本
当前Chrome版本为111.0.5563.64,但ChromeDriver是110.0.5481.77,版本不匹配是触发该问题的核心原因之一。下载与Chrome版本完全一致的ChromeDriver替换容器内的驱动文件。
2. 补充Chrome启动参数
在ChromeOptions中添加以下参数,解决容器内资源限制和渲染异常问题:
options.add_argument("--disable-dev-shm-usage") # 避免容器内/dev/shm内存不足导致崩溃 options.add_argument("--window-size=1920,1080") # 为headless模式指定足够的窗口尺寸,避免渲染错误 options.add_argument("--disable-extensions") # 禁用扩展,减少资源占用 options.add_argument("--disable-images") # 非必要时禁用图片加载,降低内存消耗(根据业务场景调整)
3. 添加显式等待机制
登录提交后页面跳转可能未完成,直接执行后续操作会导致页面崩溃。添加显式等待确保页面加载完成:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 提交登录后等待目标页面元素加载完成(替换为实际页面的特征元素) driver.find_element(By.NAME, "OK").send_keys(Keys.RETURN) WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.ID, "target-page-element-id")) )
4. 调整Docker资源配额
容器默认资源限制可能不足,启动容器时分配更多内存和CPU:
docker run -m 2g --cpus 2 your-image-name # 根据实际情况调整内存(2g)和CPU(2核)配额
5. 使用官方Selenium镜像
改用官方selenium/standalone-chrome镜像,该镜像已预配置好匹配版本的Chrome和ChromeDriver,避免手动维护版本的麻烦:
# 启动Selenium Grid节点 docker run -d -p 4444:4444 selenium/standalone-chrome:111.0
修改脚本连接远程节点:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options = webdriver.ChromeOptions() # 连接远程Selenium节点 driver = webdriver.Remote( command_executor='http://<docker-host-ip>:4444/wd/hub', options=options ) # 后续脚本逻辑保持不变 driver.get(my_url) # ...
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

