LoginSignup
2
4

More than 3 years have passed since last update.

selenium/standalone-chromeでheadlessでリモートから接続で、且つダウンロードもしたい

Posted at

関連図

selenium/standalone-chrome

diagram.png

こういう感じで繋がっている場合、chromeにダウンロードさせても操作しているruby側にはファイルがダウンロードされるわけではない(ダウンロードされるにしてもselenium/standalone-chromeのコンテナ側に入る)。

解決方法

ボリュームを使う

diagram.png

envにパスを書いておくことで、docker-compose.yml、ruby側(ENV["CHROME_DOWNLOAD_DIR"])で同じ値が参照できる。

.env
CHROME_DOWNLOAD_DIR=/chrome/downloads
docker-compose.yml
# .envがあればdocker-composeはとりあえずそれを読んでymlに反映してくれる
services:

  # /chrome/downloads
  # を共通のボリュームにしておく
  # ただそれだけだと権限の問題で書き込めないので、適当に777とかにしておく
  # $ sudo chmod 777 chrome/downloads
  chrome:
    image: selenium/standalone-chrome
    shm_size: 256m
    volumes:
      - .${CHROME_DOWNLOAD_DIR}:${CHROME_DOWNLOAD_DIR}

  backend:
    env_file:
      - .env # ファイルを指定
    build:
      context: ./backend
    working_dir: /app
    volumes:
      - ./backend:/app
      - .${CHROME_DOWNLOAD_DIR}:/app${CHROME_DOWNLOAD_DIR}

headless chromeでファイルをダウンロードする方法

一般的なseleniumの使い方ならたしかにdownload_path=入っているが、リモートだとそもそもこのモジュールが入っていないので、下のように手を加える必要がある。

Selenium::WebDriver::Chrome::Driver Selenium::WebDriver::Remote::Driver
include DriverExtensions::DownloadsFiles あり なし
...
...

driver = Capybara::Selenium::Driver.new(
  app,
  browser: :remote,
  desired_capabilities: caps,
  url: "http://#{DOCKER_CHROME_SELENIUM_HOST_NAME}:4444/wd/hub"
)
bridge = driver.browser.send(:bridge)
bridge.http.call(
:post,
"session/#{bridge.session_id}/chromium/send_command",
cmd: "Page.setDownloadBehavior",
params: { behavior: "allow", downloadPath: ENV["CHROME_DOWNLOAD_DIR"] }
)

後は/app/chrome/downloadsにファイルが入ってくるのがruby側でも見れる。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4