几年来,我们使用了在一些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)?或者,我如何安装那个不知何故擅离职守的该死的库(请参阅这个长长的页面的开头).