Selenium + Internet Explorer 11 でファイルダウンロード

Selenium WebDriver で Internet Explorer 11 を操作し、ファイルダウンロードをしようとした時にハマったのでメモ。

問題

IE 11 でファイルをダウンロードした場合、状況によって 3 種類の画面が表示されます。

  1. ダウンロードダイアログ
  2. 通知バー
  3. ダウンロードの表示 ダイアログ

これらの画面がどういうもので、どういう状況で表示されるかについては、IE サポートチームのブログ記事をご覧ください。

ファイル ダウンロード時の通知バー、ダイアログ、ダウンロードの表示と追跡について – Japan IE Support Team Blog

Selenium + IEDriver でファイルをダウンロードした場合、上記画面が表示されると WebDriver を動かしているスレッドが停止してしまいます。

StackOverflow で調べると、その画面を操作するには java.awt.Robot を使いボタン操作で対応するという回答がありますが、そもそも処理が停止されているので Robot の処理が動きません。

対応

3 種類の画面のうち、いくつか試したところほぼ 1 と 2 が表示されたため、それらに対する対応方法です。

Robot の操作を別スレッドで処理し、ダウンロード画面を操作してメインスレッドを復帰させます。

以下、Kotlin でのサンプルコードです。

import org.openqa.selenium.ie.InternetExplorerDriver
import java.awt.Robot
import java.awt.event.KeyEvent
import java.nio.file.Files
import java.nio.file.Paths
import java.time.LocalDateTime
import kotlin.concurrent.thread

fun main(args: Array<String>) {

    // IEドライバー設定
    System.setProperty("webdriver.ie.driver", "C:\\Selenium\\InternetExplorer\\IEDriverServer.exe")

    val driver = InternetExplorerDriver()

    driver.get("http://example.com/files")
    driver.get("http://example.com/files/bigdata.csv")

    // 本ブログ記事のポイント
    // 別スレッドで、Alt + S ボタンを送信し、ファイルダウンロードする。
    thread {
        Thread.sleep(2000) // ダウンロード画面が表示されるのを待つ。
        val robot = Robot()
        robot.autoDelay = 250
        robot.keyPress(KeyEvent.VK_ALT)

        Thread.sleep(1000)
        robot.keyPress(KeyEvent.VK_S)
        robot.keyRelease(KeyEvent.VK_ALT)
        robot.keyRelease(KeyEvent.VK_S)
    }

    // driver#close() を呼び出すとブラウザが終了しファイルダウンロードもされないので、ファイルがダウンロードされるまで待機。
    // これを WebDriver 側で検知する方法を見つけられておらず、ファイル名で確認するしかなさそう。
    val downloadedFilePath = "C:\\Users\\rabitarochan\\Downloads\\bigdata.csv"
    val path = Paths.get(downloadedFilePath)
    while (!Files.exists(path)) {
        println("${LocalDateTime.now()} - ファイルがありません。")
        Thread.sleep(1000)
    }

    driver.close()

上記コードでは、ファイルダウンロード中にブラウザーが終了しないよう、ダウンロードファイルの作成をチェックしています。 IEDriver では、おそらくファイルダウンロード先を実行時に制御することはできないため、ユーザープロファイル以下の Downloads フォルダーにファイルが作成されるかどうかチェックしています。

まとめ

IE 縛りの Web ページ辛い。

参考サイト