几年来,我们使用了在一些Heroku node 上运行的Ruby代码,这些 node 使用的是Selify及其ChromeDriver驱动的Chrome浏览器.一切正常,直到一周前,代码开始无法创建新的Chrome实例.阅读这篇冗长而错综复杂的侦探小说.

(...a few hours of investigating later...)原来,当Heroku在代码发布时编译插件时,heroku-buildpack-chromedriver拉出了最新的Chrome版本,即117.0.5938.88,当试图运行时,该二进制文件失败,因为找不到所需的库:

/app/.cache/selenium/chrome/linux64/117.0.5938.92/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory

(The Heroku stack we are are using is 100 which is the most recent. There's no newer version... so "upgrade your stack!" is not a correct answer.)

好的,那就是"you said that it worked before! well, then roll back to the previous version!".的确,我试过了.否则我就不会在这里问这个问题了.我不倾向于问easy个问题!

因此,很好,在以前版本的插件上可以工作(并且仍然可以工作,我们必须回滚到该插件)很好,版本如下:

> puts `which google-chrome`
/app/.apt/usr/bin/google-chrome

> puts `/app/.apt/usr/bin/google-chrome --version`
Google Chrome 115.0.5790.170 unknown

> Selenium::WebDriver::VERSION
=> "4.10.0"

> puts `which chromedriver`
/app/.chromedriver/bin/chromedriver

> puts `/app/.chromedriver/bin/chromedriver --version`
ChromeDriver 114.0.5735.90 (386bc09e8f4f2e025eddae123f36f6263096ae49-refs/branch-heads/5735@{#1052})

好的,所以我需要将所有这些都锁定到上面列出的版本.问题#1:https://github.com/heroku/heroku-buildpack-google-chrome不允许你 Select 一个特定的版本,它是only lets you to pick the "channel",然后总是会给你从该频道拉出的最新版本.很好...我不可能是唯一有这种需求的人,对吗?一定有个可怜的家伙以前遇到过同样的问题,对吧?当然有一个.让我们来看看grab his buildpack,用想要的版本号设置env变量(Chrome_Version)...耶,我们开始了!……还是are个我们?不知何故,尽管构建包工作正常,所需的Chrome版本出现在列表中,但旧的(或者,更确切地说,我们试图删除的newer Chrome版本)仍然出现在正在安装的包列表中,当轮到它安装时,它overwrites是我们想要的旧版本:

remote: -----> Installing google-chrome-stable_115.0.5790.170-1_amd64.deb
remote: -----> Installing google-chrome-stable_116.0.5845.140-1_amd64.deb

(...a few hours of investigating later...)原来Heroku有一个套餐cache!当安装了older程序包时,它不会得到适当的更新--即使不再需要它,"更现代的"程序包也不会从它中清除.好的,我们将修改构建包以强制从缓存中清除所有版本的google-chrome.Take that!

现在应该行得通了.对吧?Riiiiight?,no wai!当我们try 实例化selenium时:

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless=new')
options.add_argument('disable-dev-shm-usage')
options.add_preference(:plugins, { always_open_pdf_externally: true })
options.add_preference(:download, { prompt_for_download: false })
http_client = Selenium::WebDriver::Remote::Http::Default.new
http_client.read_timeout = 300
@driver = Selenium::WebDriver.for(:chrome, options: options, http_client: http_client)

……会发生什么事?我是认真的?不是拿起我们花了这么多时间下载的浏览器,而是顽固地使用downloads its own copy而不是使用现有的浏览器!

好吧,好吧,你不知道已经有浏览器right here了!对吗?毕竟,which google-chrome给你提供了正确的位置!你说这不是你要找的是什么意思?!好吧,好吧,别笨手笨脚的了,就用这个吧!

Selenium::WebDriver::Chrome.path = "/app/.apt/opt/google/chrome/google-chrome"

不,不是那么容易.仍然下载"较新"版本.哪一个不起作用(还记得吗,缺少库?)

在这一点上,我不知所措.我到底该怎么告诉那该死的东西用我想要的版本(S)?或者,我如何安装那个不知何故擅离职守的该死的库(请参阅这个长长的页面的开头).

推荐答案

所以,问题是,selenium拒绝启动.在花了一周多的时间试图将Chrome版本锁定到运行正常(仍然可以正常工作)的旧版本之后,我解锁了版本,希望这一故障是由Chrome的一些变化造成的.缺少库的问题确实消失了,但另一个问题出现了,Chrome抱怨Sandbox 的一些问题.幸运的是,这个问题消失了:

    myopts = Selenium::WebDriver::Chrome::Options.new
    myopts.add_argument('no-sandbox')
    driver = Selenium::WebDriver.for(:chrome, options: myopts)

现在一切都正常了,所以这个问题现在已经没有意义了.

Ruby-on-rails相关问答推荐

rails中Net::STP的多文件模式

为什么Rails数值验证器不使用规格化值?

RubyOnRail在测试环境中启动失败

包含字母和数字组合的正则表达式

删除 aws s3 (rails7) 上的日志(log)文件

在bash中匹配带有空格字符的字符串

Ruby on Rails 7 与 React 集成

Selenium chromedriver:无法从不可键入的键构造KeyEvent

如何判断是否已经在 ruby​​ on rails 的数据库事务中?

使用回形针调整图像大小

Rails,获取模型中的资源路径

如何将变量传递给render_to_string?

是否有不涉及删除 Gemfile.lock 的在任何源中找不到 *gem*错误的修复?

Rails 5:无法从参数中检索哈希值

我可以在 Ubuntu 上使用 apt-get 安装 gems 吗?

如何在同一个 Rails 控制器操作中处理多个 HTTP 方法

在 Devise on Rails beta 3 中创建管理员用户

'respond_to' 格式语句中的 `:location => ...` 和 `head :ok` 是什么意思?

何时(如果)合并 ActiveRecord 迁移?

Rails:如何将日期时间字符串解析为特定时区