python - Selenium/Chromedriver/Chromium(86) 问题 AWS Lambda

标签 python selenium selenium-chromedriver chromium

过去一周我一直在处理这个问题,但无法解决它,所以我决定寻求帮助。我正在尝试使用 Chromium 86 构建在 AWS Lambda 中运行 Selenium。我不断收到的错误消息如下:

{
  "errorMessage": "Message: unknown error: Chrome failed to start: exited abnormally.\n  (chrome not reachable)\n  (The process started from chrome location /opt/bin/chromium is no longer running, so ChromeDriver is assuming that Chrome has crashed.)\n",
  "errorType": "WebDriverException"
}

这是我的构建:

Selenium 3.14
Chromium 86.0.4240.0 (https://github.com/vittorio-nardone/selenium-chromium-lambda/blob/master/chromium.zip) which is forked from (https://github.com/puppeteer/puppeteer)
Chromedriver 86.0.4240.22.0 (https://chromedriver.storage.googleapis.com/index.html?path=86.0.4240.22/)

这是我的代码:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    chrome_options = webdriver.ChromeOptions()
#   chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--headless')
    chrome_options.add_argument("start-maximized")
    chrome_options.add_argument("disable-infobars")
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--window-size=1024x768')
    chrome_options.add_argument('--user-data-dir=/tmp/user-data')
    chrome_options.add_argument('--profile-directory=/tmp')
    chrome_options.add_argument('--hide-scrollbars')
    chrome_options.add_argument('--enable-logging')
    chrome_options.add_argument('--log-level=0')
    chrome_options.add_argument('--v=99')
#   chrome_options.add_argument('--single-process')
    chrome_options.add_argument('--data-path=/tmp/data-path')
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.add_argument('--homedir=/tmp')
    chrome_options.add_argument('--disk-cache-dir=/tmp/cache-dir')
    chrome_options.add_argument('user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.3163.100 Safari/537.36')
    chrome_options.add_argument('--remote-debugging-port=9222')
    chrome_options.binary_location = "/opt/bin/chromium"

    driver = webdriver.Chrome(executable_path="/opt/bin/chromedriver",options=chrome_options)
    driver.get('https://www.google.com/')

到目前为止我尝试过的事情:

  1. 尝试了各种运行时 Python 3.6、3.7、3.8 均未成功
  2. 尝试使用和不使用 Lambda 层。当尝试使用 Lambda 逐层文件夹结构时,相对简单:
.
├── bin
│   ├── chromedriver (binary)
│   └── chromium (binary)
└── python
    ├── selenium
    ├── selenium-3.14.0.dist-info
    ├── urllib3
    └── urllib3-1.26.7.dist-info
  • 浏览了 SO 中讨论类似问题的大部分评论示例:
  • Chrome Driver and Chromium Binaries are not working on aws lambda

    WebDriverException: Message: unknown error: Chrome failed to start: crashed error using ChromeDriver Chrome through Selenium Python on Amazon Linux ..等等

  • 尝试了我传递给 chromedriver 的几乎所有参数组合,例如 w/& w/o --disable-dev-shm-usagem、w/& w/o --disable-gpu 等。<
  • 我注意到的唯一一件事是,如果我使用某些参数,有时它会抛出selenium.common.exceptions.WebDriverException:消息:未知错误:无法在chrome中发现打开的窗口错误而不是Chrome 无法启动:异常退出 一。作为我的最后一个想法,我正在考虑编译我自己的 Chromium 86 版本。有人设法在 AWS Lambda 上运行构建 86 或更高版本吗?

    最佳答案

    更新 2022 年 1 月 2 日

    过去几天我几乎花了很多时间试图找出我的整个设置可能存在的问题。是代码吗?我使用 lambda/layers 的方式?二进制文件?运行时环境?移动部件太多,我不想回退到 Chromium 6x(这是我最后的工作设置),因为它非常古老,并且我需要的某些功能不存在......例如 Chrome DevTools 协议(protocol)的功能。

    然后我偶然发现了这个存储库,其中讨论了如何将 Amazon ECS 与 Lambda 结合使用:

    https://github.com/umihico/docker-selenium-lambda

    基本上在几分钟内我就能够设置链接到 Lambda 的容器镜像并且它正在运行:

    1. Python 3.9.8
    2. Chrome 96.0.4664.0
    3. Chromedriver 96.0.4664.45
    4. Selenium 4.1.0

    然后我移植了我的函数代码,并进行了一些更改,终于让它工作了!这是我的工作参数:

    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--disable-dev-tools')
    chrome_options.add_argument('--remote-debugging-port=9222')
    chrome_options.add_argument('--window-size=1280x1696')
    chrome_options.add_argument('--user-data-dir=/tmp/chrome-user-data')
    chrome_options.add_argument('--single-process')
    chrome_options.add_argument("--no-zygote")
    chrome_options.add_argument('--ignore-certificate-errors')
    chrome_options.binary_location = "/opt/chrome/chrome"
    
    driver = webdriver.Chrome
    driver = webdriver.Chrome("/opt/chromedriver",options=chrome_options)
    driver.get('https://www.google.com/')
    

    此设置与纯 Lambda 设置之间的主要区别在于,您使用 ECS(基于容器的)镜像,并且不运行 headless-chrome 或 serverless-chrome,而是从 chrome 快照运行守护程序。

    https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html

    关于python - Selenium/Chromedriver/Chromium(86) 问题 AWS Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70532070/

    相关文章:

    python - 如何从手部图像中获取特征向量

    python - 我在哪里可以找到 tkinter 的 API 文档?

    python - 实现最小化方法

    javascript - 无法在我的应用程序中找到下拉输入字段的元素

    java - 如何通过 Selenium Java 使用动态 xpath 将鼠标悬停在不同图像上

    java - 如何获取列表中选项标签的内部文本?

    python - 代码块中变量的作用域

    c# - IDevTools 实例不包含 CreateDevToolsSession 方法

    selenium - wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.ClassName(className)) 不返回任何元素

    google-chrome - 我可以在不使用 chromedriver.exe 的情况下为 Chrome 使用 Selenium (webdriver) 吗?