我有一个 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 的问题,也可能是我提供的路径的问题。
根据您提供的信息,问题可能出在 Chrome 安装和二进制文件路径的设置上。您尝试在 Docker 镜像中直接下载 Chrome,但这可能会导致一些问题。而且,options.binary_location 用于指定 Chrome 可执行文件的路径,而不是 Chrome 安装包的路径。在 Docker 镜像中,最好使用包管理器安装 Chrome,而不是直接下载并安装 deb 文件。
options.binary_location
以下是更新后的 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 库找到。
gdebi
dpkg
/usr/local/bin/
接下来,您可以在 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 镜像的大小。