Heroku: 在使用Watir/Selenium时无法连接到chromedriver 127.0.0.1:9515

15

这段代码可以在本地运行(不需要指定driver_path),但不能在Heroku上运行。

代码:

Selenium::WebDriver::Chrome.driver_path = ENV['GOOGLE_CHROME_SHIM']
browser = Watir::Browser.new :chrome

我已经在 Heroku 的 Rails 控制台中确认了以下数值。

ENV['GOOGLE_CHROME_BIN'] => "/app/.apt/opt/google/chrome/chrome"
ENV['GOOGLE_CHROME_SHIM'] => "/app/.apt/usr/bin/google-chrome-stable"

已安装的构建包:

https://github.com/heroku/heroku-buildpack-chromedriver
https://github.com/heroku/heroku-buildpack-google-chrome

当前错误:

Selenium::WebDriver::Error::WebDriverError: 无法连接到chromedriver 127.0.0.1:9515

在SO上搜索“unable to connect to chromedriver 127.0.0.1:9515”会返回很多结果,但没有一个提到heroku。


另外:

我考虑过phantomjs。有人在这里使其工作, Using a headless browser with Heroku Rails Unicorn stack

但它已被弃用。在本地运行时会出现以下错误。

PhantomJS的Selenium支持已被弃用。请改用Headless Chrome/Firefox或HTMLUnit。


还尝试过:

为了透明度,我还尝试了以下内容。

browser = Watir::Browser.new :chrome更改为browser = Watir::Browser.new :chrome, headless: true

虽然我并不指望这个能起作用。


另外还尝试过:

移除: https://github.com/heroku/heroku-buildpack-chromedriver

添加: https://github.com/heroku/heroku-buildpack-xvfb-google-chrome

添加headless宝石(gem)。

并运行在watir宝石页面给出的以下脚本,http://watir.com/guides/headless/

require 'watir'
require 'headless'
headless = Headless.new
headless.start
b = Watir::Browser.start 'www.google.com'
puts b.title
b.close
headless.destroy

Error:

Selenium::WebDriver::Error::UnknownError: 未知错误:无法找到 Chrome 二进制文件

我猜测这个错误是因为我没有指定 Chrome 二进制文件或者 shim 的位置。但是在文档中使用 headless 时没有找到如何指定的方法。


按建议尝试过:

heroku run /usr/bin/chromedriver --app app-name

在 ⬢ 应用名称 上运行 /usr/bin/chromedriver... up, run.2151

(Hobby) bash: /usr/bin/chromedriver: 没有那个文件或目录

此外,在部署到 Heroku 时,请参见以下涉及chrome的日志:

remote: -----> chromedriver app detected
remote: -----> Looking up latest chromedriver version...
remote: -----> Downloading chromedriver v2.33...
remote: Archive:  /tmp/chromedriver.zip
remote:   inflating: /tmp/build_cd35072c5b766edaa2b565cbff57e5d6/.chromedriver/bin/chromedriver  
remote: -----> Creating chromedriver export scripts...
remote: -----> Google Chrome app detected
...
remote: -----> Fetching https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
remote: -----> Installing google-chrome-stable_current_amd64.deb
...
remote: -----> Creating google-chrome shims

一些进展:

如果我通过 ssh 登录 heroku 服务器,

heroku run bash --app app-name

并搜索文件名为chrome的文件,

find /app/ -name "*chrome*"

/app/.profile.d/chromedriver.sh
/app/.profile.d/010_google-chrome.sh
/app/.apt/etc/cron.daily/google-chrome
/app/.apt/opt/google/chrome
/app/.apt/opt/google/chrome/chrome
/app/.apt/opt/google/chrome/chrome_100_percent.pak
/app/.apt/opt/google/chrome/chrome-sandbox
/app/.apt/opt/google/chrome/chrome_200_percent.pak
/app/.apt/opt/google/chrome/google-chrome
/app/.apt/opt/google/chrome/cron/google-chrome
/app/.apt/usr/bin/google-chrome-stable
/app/.apt/usr/bin/google-chrome
/app/.apt/usr/share/menu/google-chrome.menu
/app/.apt/usr/share/doc/google-chrome-stable
/app/.apt/usr/share/applications/google-chrome.desktop
/app/.apt/usr/share/gnome-control-center/default-apps/google-chrome.xml
/app/.apt/usr/share/man/man1/google-chrome.1
/app/.apt/usr/share/appdata/google-chrome.appdata.xml
/app/vendor/bundle/ruby/2.4.0/gems/selenium-webdriver-3.7.0/lib/selenium/webdriver/chrome
/app/vendor/bundle/ruby/2.4.0/gems/selenium-webdriver-3.7.0/lib/selenium/webdriver/chrome.rb
/app/vendor/bundle/ruby/2.4.0/gems/browser-2.4.0/test/unit/chrome_test.rb
/app/vendor/bundle/ruby/2.4.0/gems/browser-2.4.0/lib/browser/platform/chrome_os.rb
/app/vendor/bundle/ruby/2.4.0/gems/browser-2.4.0/lib/browser/chrome.rb
/app/.chromedriver
/app/.chromedriver/bin/chromedriver

我可以看到chromedriver二进制文件位于/app/.chromedriver/bin/chromedriver

因此,我尝试运行命令:

heroku run /app/.chromedriver/bin/chromedriver --app 应用程序名称

结果:

Running /app/.chromedriver/bin/chromedriver on ⬢ app-name... up, run.2067 (Hobby)
Starting ChromeDriver 2.33.506092 (733a02544d189eeb751fe0d7ddca79a0ee28cce4) on port 9515
Only local connections are allowed.

但是运行heroku run rake selenium_namespace:task_one --app app-name结果相同。

Selenium::WebDriver::Error::WebDriverError: 无法连接到chromedriver 127.0.0.1:9515 ... /app/vendor/ruby-2.4.1/lib/ruby/2.4.0/net/http.rb:906:in `rescue in block in connect': 打开TCP连接到127.0.0.1:9515失败(拒绝连接 - connect(2) for "127.0.0.1" port 9515)(Errno::ECONNREFUSED) ...


当在Heroku主机上运行heroku run /usr/bin/chromedriver时,Heroku主机的输出是什么?这应该手动在您的Heroku服务器上运行Chrome驱动程序,可能某些依赖项未安装。https://dev59.com/4GIj5IYBdhLWcg3ws3Ff - Fabrizio Bertoglio
@FabrizioBertoglio 我已经根据您的建议更新了问题。这是否听起来像缺少依赖项? - tim_xyz
我们已经将其启动,也许我们的答案能以同样的方式帮助您。https://dev59.com/KKTja4cB1Zd3GeqPGsBK#50781946 - anka
在Ubuntu上,您可以执行“sudo apt-get install chromium-browser”命令进行安装,但我不确定如何在Heroku上执行此操作。 - pguardiario
1
这个解决方案对我起作用了。 - stevec
4个回答

4

这在Heroku上是可行的。


混淆了chromechromedriver

您的配置混淆了chromedriverChrome GOOGLE_CHROME_SHIM指向Chrome 可执行文件google-chrome-stable ,而不是chromedriver。下面这行代码导致Selenium执行错误的二进制文件,从而导致误导性的错误消息。

Selenium::WebDriver::Chrome.driver_path = ENV['GOOGLE_CHROME_SHIM'] # WRONG!

截至编写本文(2018年1月),chromedriver构建包会自动将/app/.chromedriver/bin添加到$PATH变量中。如果您删除上述行,则Selenium应该能够自动找到chromedriver
然后呢?
您可能已经添加了上面的行来修复Selenium无法找到Chrome二进制文件的问题。那个错误消息看起来像这样:

Selenium::WebDriver::Error::UnknownError: unknown error: cannot find Chrome binary

您可以通过告诉Selenium Chrome二进制文件的位置来解决此问题,使用Selenium::WebDriver::Chrome::Options。以下代码应该可以实现这一点。
options = Selenium::WebDriver::Chrome::Options.new
chrome_bin_path = ENV.fetch('GOOGLE_CHROME_SHIM', nil)
options.binary = chrome_bin_path if chrome_bin_path # only use custom path on heroku
options.add_argument('--headless') # this may be optional
driver = Selenium::WebDriver.for :chrome, options: options
driver.navigate.to "https://stackoverflow.com"

构建包

使用标准的 chromechromedriver 构建包应该可以实现所有这些:

https://github.com/heroku/heroku-buildpack-google-chrome.git https://github.com/heroku/heroku-buildpack-chromedriver.git

如果您要在浏览器中自动点击,则可能需要使用 heroku-buildpack-xvfb-google-chrome 而不是普通的 chrome,但这不应该是运行无头 chrome 的必要条件。


2
我引用了Ilya Vassilevsky在这个帖子中的话:

ChromeDriver只是Chrome的一个驱动程序。它需要实际安装在同一台机器上的Chrome浏览器才能正常工作。

Heroku默认情况下不在其dynos上安装Chrome。您需要使用一个安装Chrome的构建包。例如:

https://github.com/dwayhs/heroku-buildpack-chrome

您可以看到它如何获取Chrome:

https://github.com/dwayhs/heroku-buildpack-chrome/blob/master/bin/compile#L36-38

然后我阅读了他们在评论中的讨论:

Petr Gazarov说:

尝试过这个构建包,但它没有起作用。我怀疑在Heroku上安装Google Chrome(或任何浏览器)可能需要更多的操作。
Ilya Vassilevsky回答道:“是的,Heroku是一个非常有主见和封闭的平台。在AWS、Linode或DigitalOcean上自己设置Chrome和ChromeDriver应该会更容易。”
Petr Gazarov回答道:“谢谢您的回答,Ilya。最终我用PhantomJS重写了Watir,因为我无法让Heroku安装Chrome。”
您可以在那个问题中阅读更多信息。如果我想到什么,我会发帖的。

希望我不需要在Digital Ocean上使用迷你应用程序来完成这个任务。但是我同意,鉴于PhantomJS已经被弃用,那可能是唯一的选择。 - tim_xyz
我遇到了与 OP 相同的问题。我发布了一个单独的答案来解决它。在 Heroku 上绝对是可行的。 - laverick

2

这对我很有帮助。我替换了下面的行:

Selenium::WebDriver::Chrome.driver_path = ENV['GOOGLE_CHROME_SHIM']

对于这个问题:

Selenium::WebDriver::Chrome::Service.driver_path = "/app/.chromedriver/bin/chromedriver"

1
Stack Overflow 是一个英文网站。您能用英语回答吗? - wovano

0

我已经为此苦苦挣扎了几个小时....

在Heroku CI上尝试调试非常令人沮丧。这张票据帮助我找到了解决方案。

我在spec_helper.rb中有一段代码引起了问题(如果对某人有帮助):

config.before(:each, type: :system, js: true) do
  driven_by :selenium_chrome_headless
end

它正在绕过所有的capybara设置...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接