小能豆

Selenium Chrome 无法在 Docker 容器中启动

python

我有一个 Flask 后端,它使用 Selenium 来抓取一些信息,并且我创建了一个 Docker 映像来下载 Chrome 和执行此操作所需的 Chromedriver。这是我的 Dockerfile:

FROM python:3.11.4-slim-bookworm

RUN  apt-get update \
  && apt-get install -y wget unzip \
  && rm -rf /var/lib/apt/lists/*

RUN apt-get update \ 
  && apt-get install -y libglib2.0-0 \
  libnss3 \
  libgconf-2-4 \
  libfontconfig1 \
  libxcb1

# install chrome directly
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN dpkg -i google-chrome-stable_current_amd64.deb --fix-missing; apt-get -fy install

# install chromedriver
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

WORKDIR /app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]

之前我是通过 apt-get install 安装 Chromium 的,而不是直接下载,这样可以,但我想为 Docker 镜像节省一些空间,所以我尝试了这种方法。当我运行创建 Chromedriver 的脚本时,出现以下错误:

selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /google-chrome-stable_current_amd64.deb is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

我安装的 Chrome 下载到根目录“/google-chrome-stable_current_amd64.deb”,而不是 Chromedriver 在“/usr/bin/chromium”中查找的默认路径,我设置了二进制文件位置,但是好像还是不行。

options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox')
options.add_argument('--headless=new')
options.binary_location = "/google-chrome-stable_current_amd64.deb"

driver = webdriver.Chrome(options=options)

我不确定问题是什么,可能是我正在下载的 Chrome 的问题,也可能是我提供的路径的问题。


阅读 164

收藏
2023-07-28

共1个答案

小能豆

根据您提供的信息,问题可能出在 Chrome 安装和二进制文件路径的设置上。您尝试在 Docker 镜像中直接下载 Chrome,但这可能会导致一些问题。而且,options.binary_location 用于指定 Chrome 可执行文件的路径,而不是 Chrome 安装包的路径。在 Docker 镜像中,最好使用包管理器安装 Chrome,而不是直接下载并安装 deb 文件。

以下是更新后的 Dockerfile,它使用包管理器来安装 Chrome:

FROM python:3.11.4-slim-bookworm

RUN  apt-get update \
  && apt-get install -y wget unzip \
  && rm -rf /var/lib/apt/lists/*

# Install Chrome and its dependencies
RUN apt-get update \
  && apt-get install -y libglib2.0-0 \
  libnss3 \
  libgconf-2-4 \
  libfontconfig1 \
  libxcb1 \
  gdebi-core \
  && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
  && gdebi --n google-chrome-stable_current_amd64.deb

# Install chromedriver
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_linux64.zip \
  && unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

WORKDIR /app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]

在此更新的 Dockerfile 中,我们使用 gdebi 来安装 Chrome,这是因为它能够处理依赖关系,而直接使用 dpkg 可能会导致缺少依赖项的错误。然后,我们将 Chromedriver 下载并解压到 /usr/local/bin/,这样它就能被 Python 的 Selenium 库找到。

接下来,您可以在 Python 代码中使用以下方式来创建 Chrome WebDriver:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox')
options.add_argument('--headless')

driver = webdriver.Chrome(options=options)

注意,我们不再设置 options.binary_location,因为我们使用包管理器安装了 Chrome,所以 Selenium 库可以自动找到正确的可执行文件路径。

请注意,为了获得最佳的 Docker 镜像大小优化,您可能还需要在构建 Docker 镜像时清理安装文件和缓存,以减少镜像的大小。可以在安装 Chrome 和 Chromedriver 之后,添加以下命令来进行清理:

RUN apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
  && rm -rf google-chrome-stable_current_amd64.deb

这将删除不再需要的安装文件和缓存,从而减小 Docker 镜像的大小。

2023-07-28