Selenium Python脚本无法在Docker容器中运行的问题求助
问题
我有一个需要在Docker中运行的Selenium解析脚本,本地机器运行完全正常,但在容器内运行时,所有元素查找操作都会触发“元素未找到”错误。我推测是Selenium在Docker环境中无法正常运行,或是无法与Chrome浏览器正确集成。
我已经尝试在容器内安装Chrome浏览器与ChromeDriver,也试过使用独立容器部署的远程驱动,但结果始终一致。优先希望不使用远程驱动解决问题,求各位给出建议,谢谢!
我的Dockerfile
FROM python:3.10-slim-buster RUN mkdir -p /usr/src/app/ WORKDIR /usr/src/app/ COPY . /usr/src/app/ RUN pip install --no-cache-dir -r requirements.txt RUN apt-get update \ && apt-get install -y wget \ && apt-get install -y gnupg2 \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* # install google chrome RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' RUN apt-get -y update RUN apt-get install -y google-chrome-stable # install chromedriver RUN apt-get install -yqq unzip RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/src/app/chromedriver/ CMD python3 ./script.py
我的Python脚本
from selenium import webdriver from selenium.webdriver.chrome.service import Service service = Service(r'chromedriver/chromedriver') options = webdriver.ChromeOptions() options.add_argument('--no-sandbox') # webdriver mode options.add_argument('--disable-blink-features=AutomationControlled') # user-agent options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/103.0.0.0 Safari/537.36") options.add_argument('--window-size=1420,1080') # headless mode options.add_argument('--headless') options.add_argument('--disable-gpu') # incognito mode options.add_argument("--incognito") options.add_experimental_option("excludeSwitches", ["enable-logging"]) driver = webdriver.Chrome( service=service, options=options )
解决方案
1. 确保Chrome与ChromeDriver版本严格匹配
你的Dockerfile中安装的是最新版ChromeDriver,但Chrome是stable分支版本,可能出现版本不兼容。可以:
- 安装Chrome时指定具体版本,再下载对应版本的ChromeDriver;
- 或者使用
webdriver-manager自动匹配安装,无需手动下载ChromeDriver。
2. 补充Chrome运行依赖
slim镜像缺少Chrome运行必需的系统库,需添加以下安装命令:
RUN apt-get update && apt-get install -y \ libglib2.0-0 \ libnss3 \ libgconf-2-4 \ libfontconfig1 \ libx11-6 \ libx11-xcb1 \ libxcb1 \ libdbus-1-3 \ && rm -rf /var/lib/apt/lists/*
3. 调整Chrome启动参数
容器环境下需要补充和修改部分参数:
- 将
--headless替换为--headless=new(旧版headless模式在容器中可能存在渲染问题); - 添加
--disable-dev-shm-usage,避免容器共享内存不足导致Chrome崩溃; - 确保
--no-sandbox参数保留(容器中必须开启)。
修改后的options示例:
options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--headless=new') # 替换旧的--headless
4. 修复ChromeDriver权限与路径
给ChromeDriver添加执行权限,或者将其放入系统PATH:
RUN chmod +x /usr/src/app/chromedriver/chromedriver # 或者直接将chromedriver移到/usr/local/bin/,这样脚本中无需指定路径 RUN mv /usr/src/app/chromedriver/chromedriver /usr/local/bin/
对应脚本中可以简化为:
service = Service() # 自动从PATH查找chromedriver
5. 优化后的完整Dockerfile示例
FROM python:3.10-slim-buster WORKDIR /usr/src/app/ COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 安装系统依赖 RUN apt-get update && apt-get install -y --no-install-recommends \ wget gnupg2 curl unzip \ libglib2.0-0 libnss3 libgconf-2-4 libfontconfig1 \ libx11-6 libx11-xcb1 libxcb1 libdbus-1-3 \ && rm -rf /var/lib/apt/lists/* # 安装Chrome RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list RUN apt-get update && apt-get install -y google-chrome-stable && rm -rf /var/lib/apt/lists/* # 安装对应版本的ChromeDriver RUN CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+\.\d+') \ && wget -O /tmp/chromedriver.zip https://chromedriver.storage.googleapis.com/$(curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROME_VERSION%.*})/chromedriver_linux64.zip \ && unzip /tmp/chromedriver.zip -d /usr/local/bin/ \ && chmod +x /usr/local/bin/chromedriver \ && rm /tmp/chromedriver.zip COPY . . CMD python3 ./script.py
6. 脚本额外建议
- 添加显式等待(
WebDriverWait)替代隐式等待,避免页面未加载完成就查找元素; - 捕获异常并打印页面源码,排查是否页面加载异常。
示例显式等待代码:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待元素出现,最多10秒 element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "element-id")) )
内容的提问来源于stack exchange,提问作者Eldellano
相关产品推荐
相关产品推荐

