Ubuntu下ChromeDriver 120无头模式随机崩溃:session deleted报错求助
问题描述
在Ubuntu系统上使用ChromeDriver 120搭配Chrome 120运行Selenium测试时,随机出现「chrome not reachable」或「session deleted because of page crash」错误。崩溃无固定规律:有时脚本可连续成功运行10次以上,有时首次运行就失败,且无特定页面或操作触发该问题。使用RemoteWebDriver指向本地Chrome实例时也存在相同现象。
现有配置代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--headless") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--disable-gpu") options.add_argument("--window-size=1920,1080") driver = webdriver.Chrome(options=options) try: driver.get("https://example.com") print(driver.title) finally: driver.quit()
报错日志
DevTools listening on ws://127.0.0.1:44691/devtools/browser/abc123... [04123:04123:0429/153412.567:ERROR:chrome_browser_main_extra_parts_metrics.cc(123)] SOME ERROR MESSAGE [04123:04123:0429/153412.789:ERROR:some_file.cc(456)] Chromium browser process crashed (code 11) selenium.common.exceptions.WebDriverException: Message: unknown error: session deleted because of page crash from chrome not reachable
排查方向与解决方案
1. 补充Chrome启动参数,增强稳定性
在现有参数基础上,添加以下参数减少冲突与资源占用:
import os options.add_argument("--disable-extensions") # 禁用扩展,避免冲突 options.add_argument("--disable-plugins") # 禁用插件 options.add_argument("--disable-software-rasterizer") # 禁用软件光栅化,减少渲染崩溃 options.add_argument("--disable-background-networking") # 禁用后台网络请求 options.add_argument("--disable-background-timer-throttling") # 禁用后台定时器节流 options.add_argument("--disable-backgrounding-occluded-windows") # 禁用遮挡窗口后台化 options.add_argument("--disable-renderer-backgrounding") # 禁用渲染进程后台化 options.add_argument("--force-device-scale-factor=1") # 强制缩放系数,避免渲染异常 # 使用带进程ID的临时用户目录,避免并发测试冲突 options.add_argument(f"--user-data-dir=/tmp/chrome_test_profile_{os.getpid()}")
2. 排查系统资源问题
- 检查内存与共享内存:
执行free -h查看系统内存,若/dev/shm空间不足,手动挂载更大的tmpfs:
(可写入sudo mount -t tmpfs -o size=2G tmpfs /dev/shm/etc/fstab实现永久生效) - 检查OOM Killer日志:
执行dmesg | grep -i oom,若发现Chrome进程被OOM Killer杀掉,说明系统内存不足,可添加参数限制Chrome内存:options.add_argument("--max-old-space-size=1024") # 限制V8内存为1G - 清理残留进程:
在测试前后强制清理Chrome残留进程:pkill -f chrome
3. 验证版本兼容性
- 重新确认版本匹配:
执行google-chrome --version和chromedriver --version,确保版本号完全一致,重新下载对应版本的ChromeDriver替换现有文件 - 尝试版本切换:
暂时降级到Chrome 119+ChromeDriver 119,或升级到最新稳定版Chrome 121+对应Driver,验证是否为120版本的已知bug
4. 优化测试框架
- 添加重试机制:
捕获崩溃错误,自动重试指定次数:
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import WebDriverException
MAX_RETRIES = 3
def run_test():
options = Options()
# 插入所有优化后的启动参数
options.add_argument("--headless")
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_argument("--disable-extensions")
options.add_argument(f"--user-data-dir=/tmp/chrome_test_profile_{os.getpid()}")
driver = None try: driver = webdriver.Chrome(options=options) driver.get("https://example.com") print(driver.title) return True except WebDriverException as e: print(f"测试失败: {e}") return False finally: if driver: driver.quit() os.system("pkill -f chrome")
if name == "main":
retries = 0
success = False
while retries < MAX_RETRIES and not success:
success = run_test()
retries += 1
if not success:
print(f"已重试{MAX_RETRIES}次,仍失败")
- 自动管理Driver版本: 安装`webdriver-manager`自动匹配Chrome版本: ```bash pip install webdriver-manager
代码修改为:
from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
5. 增强日志调试
- 开启Chrome详细日志:
添加参数将日志输出到文件:
options.add_argument("--enable-logging")
options.add_argument("--v=1")
options.add_argument("--log-path=/tmp/chrome_debug.log")
- 开启ChromeDriver日志: 初始化时指定日志路径: ```python from selenium.webdriver.chrome.service import Service service = Service(log_path='/tmp/chromedriver.log') driver = webdriver.Chrome(service=service, options=options)
查看日志文件,定位崩溃的具体原因(如渲染模块崩溃、内存泄漏等)
内容的提问来源于stack exchange,提问作者Gökhan

