Selenium搭配Chromium在Ubuntu无头模式下卡在缓存驱动找到后无法创建会话的问题排查
Selenium搭配Chromium在Ubuntu无头模式下卡在缓存驱动找到后无法创建会话的问题排查
看起来你遇到的是Ubuntu环境下Chromium无头模式启动时的经典DevToolsActivePort file doesn't exist问题,我来帮你一步步排查和解决这个问题。
错误原因分析
这个报错本质上是Chromium启动时无法成功创建DevTools的通信端口,导致Selenium无法和浏览器建立会话。常见的诱因包括:
- 无头模式下端口自动分配失败
- 沙箱机制限制了浏览器进程的启动
- ChromeDriver与Chromium的适配细节(即使版本号匹配,Chrome和Chromium的驱动也可能存在细微差异)
- 启动参数组合冲突或缺失关键参数
具体修复步骤
1. 调整Chromium启动参数,解决端口分配问题
在你的ChromeOptions中添加--remote-debugging-port参数明确指定可用端口,同时建议切换到Chromium的新无头模式(兼容性和稳定性更好):
options = webdriver.ChromeOptions() options.binary_location = '/usr/bin/chromium-browser' # 改用新无头模式替代旧的--headless options.add_argument('--headless=new') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-gpu') options.add_argument('--disable-blink-features=AutomationControlled') options.add_argument('--disable-extensions') # 明确指定调试端口,避免自动分配失败 options.add_argument('--remote-debugging-port=9222') options.add_argument('--window-size=1920,1080') # --disable-setuid-sandbox可移除,--no-sandbox已包含该功能
2. 确保ChromeDriver与Chromium严格适配
你当前使用的ChromeDriverManager()默认下载Chrome驱动,而非Chromium专用驱动。即使版本号匹配,两者仍可能存在适配问题,修改配置指定下载Chromium驱动:
首先导入ChromeType:
from webdriver_manager.chrome import ChromeDriverManager, ChromeType
然后修改Service创建代码:
service = Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install())
3. 验证浏览器二进制文件的权限与路径
- 确认Chromium路径正确性:
确保输出和代码中指定的which chromium-browser/usr/bin/chromium-browser一致。 - 检查文件执行权限:
确保当前用户拥有执行权限(权限列包含ls -l /usr/bin/chromium-browserx)。 - 可选:手动给ChromeDriver添加执行权限(WebDriver Manager通常会自动处理,但可兜底验证):
chmod +x /home/shane/.wdm/drivers/chromedriver/linux64/132.0.6834.83/chromedriver-linux64/chromedriver
4. 优化日志输出,定位卡顿时点
在create_driver函数中增加细粒度日志,明确哪一步执行卡滞:
@contextmanager def create_driver(): driver = None try: options = webdriver.ChromeOptions() # 省略其他参数配置... logging.info("Starting to install/verify ChromeDriver...") service = Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()) logging.info("ChromeDriver ready, attempting to launch Chromium...") driver = webdriver.Chrome(service=service, options=options) logging.info("WebDriver created successfully.") yield driver # 省略异常处理和finally块...
修改后的完整代码示例
from datetime import datetime import logging from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager, ChromeType from contextlib import contextmanager logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(), logging.FileHandler('app.log', mode='a') ] ) @contextmanager def create_driver(): driver = None try: options = webdriver.ChromeOptions() options.binary_location = '/usr/bin/chromium-browser' # 确认路径正确 options.add_argument('--headless=new') # 新无头模式更稳定 options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-gpu') options.add_argument('--disable-blink-features=AutomationControlled') options.add_argument('--disable-extensions') options.add_argument('--remote-debugging-port=9222') # 明确指定调试端口 options.add_argument('--window-size=1920,1080') logging.info("Preparing ChromeDriver service...") service = Service(ChromeDriverManager(chrome_type=ChromeType.CHROMIUM).install()) logging.info("Launching Chromium browser...") driver = webdriver.Chrome(service=service, options=options) logging.info("WebDriver created successfully.") yield driver except Exception as e: logging.error(f"Error creating WebDriver: {e}") if driver: driver.quit() raise finally: if driver: driver.quit() logging.info("WebDriver closed successfully.") def search_web(query): try: with create_driver() as driver: url = 'https://www.example.com/' logging.info(f"Navigating to search page: {url}") driver.get(url) logging.info(f"Successfully loaded page: {driver.title}") return "complete" except Exception as e: logging.error(f"Error during web search: {e}") return f"Error performing search: {str(e)}" if __name__ == '__main__': result = search_web("Hello") print(result.strip())
测试与验证
- 运行修改后的代码,观察日志输出,如果能看到
WebDriver created successfully.和Successfully loaded page: Example Domain,说明问题解决。 - 如果仍然报错,可以尝试暂时移除部分非必要参数(比如
--disable-blink-features=AutomationControlled),逐步排查参数冲突。
备注:内容来源于stack exchange,提问作者user29255210
相关产品推荐
相关产品推荐

