chromedriverのheadlessでファイルをダウンロードする
headlessではないGUIでのコード
まず通常モードでの実装です。
ダウンロード先のパスを指定するダイアログを表示しないようにして、
ダウンロード先のパスを指定します。
今回はコードと同ディレクトリの tmp フォルダを指定します。
1 2 3 4 5 6 7 8 9 10 |
prefs = { :download => { :prompt_for_download => false, :default_directory => File.absolute_path("./tmp") } } d = Selenium::WebDriver.for :chrome, prefs: prefs # この後にダウンロードリンクをクリックするコードを書く |
headlessモードでの実装
さっきのコードに単純にheadlessのオプションも渡して実行してもファイルが保存されません。
こんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 |
prefs = { :download => { :prompt_for_download => false, :default_directory => File.absolute_path("./tmp") } } caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {prefs: prefs, args: ["--headless", "window-size=1280x800"] } ) d = Selenium::WebDriver.for :chrome,desired_capabilities: caps # この後にダウンロードリンクをクリックするコードを書く |
これではどこにも保存されませんでした。
正解はこうでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
options = Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-gpu') options.add_argument('--disable-popup-blocking') options.add_argument('--window-size=1366,768') d = Selenium::WebDriver.for :chrome, options: options bridge = d.send(:bridge) path = "/session/#{bridge.session_id}/chromium/send_command" command_hash = { cmd: 'Page.setDownloadBehavior', params: { behavior: 'allow', downloadPath: File.absolute_path('./tmp').gsub(/\//, "\\") } } bridge.http.call(:post, path, command_hash) # この後にダウンロードリンクをクリックするコードを書く |
これでいけました。
pathのgsubはwindowsで実行する場合に必要で、linuxでは不要です。
単純に今のchromedriver 2.38(2018/5/2現在)が非対応なだけだとは思いますが、
とりあえずはこれでいけます。