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

Heroku: unable to connect to chromedriver 127.0.0.1:9515 when using Watir/Selenium

这在本地运行(未指定 driver_path),但不在 Heroku 上运行。

代码:

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

我已经在 heroku rails console

中确认了以下值
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: unable to connect to chromedriver 127.0.0.1:9515

在 SO unable to connect to chromedriver 127.0.0.1:9515 上搜索 returns 一堆结果,但 none 提到了 heroku。


另外:

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

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

Selenium support for PhantomJS is deprecated. Use headless Chrome/Firefox or HTMLUnit instead.


也尝试过:

为了透明,我还尝试了以下方法。

改变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 gem 页面中给出的以下脚本,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

错误:

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

我假设这失败了,因为我没有指定 chrome binary/shim 的位置。在文档中使用 headless 时找不到如何指定它。


尝试了每个建议:

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

Running /usr/bin/chromedriver on ⬢ app-name... up, run.2151

(Hobby) bash: /usr/bin/chromedriver: No such file or directory

另请参阅下面的日志,在部署到 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

我可以在 /app/.chromedriver/bin/chromedriver 看到 chrome 驱动程序二进制文件。

所以我试了

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

结果:

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: unable to connect to 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': Failed to open TCP connection to 127.0.0.1:9515 (Connection refused - connect(2) for "127.0.0.1" port 9515) (Errno::ECONNREFUSED) ...

我在引用Ilya Vassilevsky from this

ChromeDriver is just a driver for Chrome. It needs the actual Chrome browser installed on the same machine to actually work.

Heroku doesn't have Chrome installed on its dynos by default. You need to use a buildpack that installs Chrome. For example:

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

You can see how it fetches Chrome:

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

然后我在评论里看了他们的讨论:

彼得加扎罗夫

I tried this buildpack and it didn't work. I'm suspecting installing google chrome (or any browser) on heroku might be more involved.

Ilya Vassilevsky 回复

Yes, Heroku is a very opinionated and closed platform. It should be much easier to set up Chrome with ChromeDriver on your own VM on AWS, Linode, or DigitalOcean.

Petr Gazarov 回复

Thanks for your answer Ilya. I ended up re-writing with Watir with phantomjs because I couldn't get Heroku to install Chrome.

您可以在该问题中阅读更多信息。 如果我想到什么,我会 post 它。

这在 Heroku 上是可能的。


混淆 chromechromedriver

您的配置混淆了 chrome驱动程序ChromeGOOGLE_CHROME_SHIM 指向 Chrome 可执行文件 google-chrome-stable,而不是 chrome 驱动程序 。下面的行导致 Selenium 执行错误的二进制文件,从而导致误导性错误消息。

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

截至撰写本文时(18 年 1 月),chromedriver 构建包自动将 /app/.chromedriver/bin 添加到 $PATH 变量。如果您 删除 上面的行 Selenium 应该能够再次自动找到 chromedriver

然后呢?

您可能添加了上面的行来修复 Selenium 无法找到 Chrome 二进制文件的问题。该错误消息类似于:

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

您可以通过使用 Selenium::WebDriver::Chrome::Options 告诉 Selenium Chrome 二进制文件所在的位置来解决此问题。下面的代码应该可以做到这一点。

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://whosebug.com"

构建包

标准 chromechromedriver 构建包应该都可以实现:

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

如果您要在浏览器中自动点击,您可能需要 heroku-buildpack-xvfb-google-chrome 而不是 vanilla chrome,但应该 而不是 只是为了获得无头 chrome 运行.

我已经为这个问题苦苦挣扎了几个小时....

尝试在 Heroku CI 上进行调试非常令人沮丧。这张票对我找到解决方案帮助很大。

我在 spec_helper.rb 中有这段代码引起了麻烦(如果它对某人有帮助的话):

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

它绕过了所有水豚设置...

这对我有用。我替换了下面的行:

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

为此:

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