首页 > 解决方案 > Flask API 和 Selenium 脚本在一个容器中

问题描述

我已经容器化了一个监听 HTTP 请求的 Flask API。当我向特定端点发送 POST 请求时,API 会触发一个无头 Selenium 脚本。

虽然,我对容器部署和 API 没有任何问题(安装了依赖项并满足了要求),但我在 selenium 脚本中遇到了错误。这些错误与应单击的按钮和其他 HTML 元素有关,并且由于某种原因自动化脚本无法找到它们。奇怪的是,如果我在容器外部、本地从 venv 运行这个 python-selenium 脚本,它运行没有问题并按预期执行自动化。

该容器托管在 GCP Cloud Run 上,我已按照 GCP 文档创建 Flask API。

Dockerfile 配置如下:

# Base Image
FROM ubuntu:20.04

# Environment variables, setting app home path and copy of the python app in the container
ENV PYTHONUNBUFFERED True

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

# Update/upgrade the system
RUN apt -y update
RUN apt -y upgrade

# Install App dependencies and chrome webdriver
RUN apt install -yqq unzip curl wget python3-pip
RUN DEBIAN_FRONTEND="noninteractive" apt-get -y install tzdata
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb
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/local/bin/

# Install Python dependencies
RUN pip install Flask gunicorn selenium pyotp

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

main.py 中的 API 代码可以在下面找到:

import os
from flask import Flask, request, abort
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from pyotp import *
import time

app = Flask(__name__)

@app.route("/endpoint", methods=['POST'])
def endpoint():
    if request.method == 'POST':

        print(request.json)
        # new options
        chrome_options = Options()
        chrome_options.add_argument('--no-sandbox')
        chrome_options.add_argument('--headless')
        chrome_options.add_argument("--disable-setuid-sandbox")
        # other options
        chrome_options.add_argument("--disable-extensions")
        chrome_options.add_argument("--disable-gpu")
        chrome_options.add_argument('--ignore-certificate-errors')
        # chrome_options.headless = True

        # initialize the Chrome driver with options
        driver = webdriver.Chrome(options=chrome_options)

        # Set Resolution to 1920x1080
        driver.set_window_size(1920, 1080, driver.window_handles[0])

        # Main code for the automations goes here, login, OTP 
        # find elements by xpath and send keys or make clicks to HTML

    
        # Getting current URL
        get_url = driver.current_url

        # Printing the URL
        print(get_url)

        # close the driver
        driver.quit()

        return 'Success', 200

    else:
        abort(400)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

执行因“找不到 xpath 的元素”和类似错误而停止。RAM 足以运行容器。

我更喜欢使用 Cloud Run,而不是 App Engine 或 VM 实例。

我错过了什么?有什么建议么?

标签: pythonseleniumflask

解决方案


推荐阅读