2017年10月21日土曜日

JShellを使ってJavaだけでSelenium (ChromeDriver) を動かす。

はじめに

Mirror House Lab: Nashornを使ってJavaScriptを書いてSelenium (ChromeDriver) を動かす。で、
「もうすぐjshellを含むJava SE 9がリリースされてJavaをスクリプトとして実行できるようになるだろうに、何をやっているんだ」という気もしているけれど、Java SE 8環境ですぐに動かしたかったので。
と言っていた。

Java SE 9がリリースされたのでJShellで動かす方法について書く。

環境と準備

環境は以下の通り。
  • OS: Windows 10 (64bit)
  • JDK: 9
  • Selenium Standalone Server: 3.6.0
  • Chrome: 61
  • ChromeDriver: 2.33

SeleniumとChromeDriverの準備作業は変わらない。ただしNashhornとJShellでクラスパスの通し方が異なる(後述)。JDKとChromeはインストール済みとする。

Selenium: DownloadsからSelenium Standalone Serverをダウンロードする。保存先フォルダにパスを通すのは必須ではない。JShellはオプションでもコマンドでもクラスパスを指定できる。この記事ではコマンドで指定する方法を採用する。

ChromeDriver: Downloads - ChromeDriver - WebDriver for Chromeから、chromedriver_win32.zipをダウンロードして展開する。Windows 64bit用は提供されていないので32bit用を使う。こちらも保存先にパスを通すのは必須ではない。Javaの場合、プロパティに設定できる。このエントリィではその方法を採用する。

サンプルコード

クラスパスを通すのはJShellのコマンド。あとはJavaなので取り立てて言うことはない。
// jshell-selenium.jsh
/env -class-path C:\path\to\selenium-server-standalone-3.6.0.jar;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

String pathToChromeDriver = "C:\\path\\to\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", pathToChromeDriver);

ChromeDriver driver = new ChromeDriver();
driver.get("http://www.google.com/xhtml");
Thread.sleep(5000);
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys("ChromeDriver");
searchBox.submit();
Thread.sleep(5000);
driver.quit();

実行方法

最初はJShellを起動して、下記を実行する。
> /open C:\path\to\jshell-selenium.jsh

2回目以降、そのまま繰り返すときは/reloadコマンド。

スクリプトファイルを修正して再実行するなら、/resetコマンドを実行してから、/openコマンド。JShellは/listで表示されるコードを実行するのだけれど、/openコマンドは追記して実行するので、もう1回/openコマンドでスクリプトファイルを読み込むと2回実行される。

クラスパスの通し方

クラスパスは、JShell起動時にコマンドラインオプションで渡すこともできる。External Codeの"Setting The Class Path"を参照。

Java 9なのでクラスパスではなくてモジュールも使える(External Codeの"Setting Module Options")。でも、そのモジュールをまだよく分かっていないので、まずはそちらから調べないと。

感想

Javaで書けるので言語差分を考えなくてよいのと、ちょっとデバッグしているときにJShell上で補完が効くのが助かる。

References

2017年7月15日土曜日

Nashornを使ってJavaScriptを書いてSelenium (ChromeDriver) を動かす。

はじめに

開発環境ではない環境で、ちょっとしたブラウザ操作を自動化するのに使った方法について書く。

具体的には、Nashorn (Java SE 8で追加されたJavaScriptエンジン。Rhinoの後継) を使い、JavaScriptを書いてSelenium Standalone Serverを呼び出し、ChromeDriverでChromeを自動操作する方法。

「Selenium Standalone ServerはJarなのだから、素直にJavaから呼んだら?」とか、「JavaScriptで書くならSelenium Client & WebDriver Language BindingsのJavaScript (node)を使うのが自然では?」とも思うのも、ごもっとも。自分もそう思う。

それでもこの方法を調べたのは、環境準備が楽だから。JREさえインストールされていれば、あとはSeleniumをダウンロードするだけ。Eclipse, JDK, node.jsどれも必要ない。

「もうすぐjshellを含むJava SE 9がリリースされてJavaをスクリプトとして実行できるようになるだろうに、何をやっているんだ」という気もしているけれど、Java SE 8環境ですぐに動かしたかったので(※2017/10/21追記: JShellでも動かしてみた)。

環境と準備

環境は以下の通り。
  • OS: Windows 10 (64bit)
  • JRE: 8
  • Selenium Standalone Server: 3.4.0
  • Chrome: 59
  • ChromeDriver: 2.30

SeleniumとChromeDriverの準備作業は以下の通り。JREとChromeはインストール済みとする。

Selenium: DownloadsからSelenium Standalone Serverをダウンロードする。保存先フォルダにパスを通すのは必須ではない。Nashornを起動するときにオプションでクラスパスを指定できる。この記事ではその方法を採用する。

ChromeDriver: Downloads - ChromeDriver - WebDriver for Chromeから、chromedriver_win32.zipをダウンロードして展開する。Windows 64bit用は提供されていないので32bit用を使う。こちらも保存先にパスを通すのは必須ではない。Javaの場合、プロパティに設定できる。このエントリィではその方法を採用する。

サンプルコード

ポイントはJavaクラスへのアクセス。標準JavaパッケージのクラスにアクセスするにはFQCNを使う。それ以外のクラス(ここではorg.openqa.seleniumパッケージのクラス)にアクセスするには、Java.type('FQCN')を使う。
// nashorn-selenium.js

// グローバル変数/関数を作らないため即時関数呼び出し。
// 『メンテナブルJavaScript』の「6.4 0-グローバルのアプローチ」参照。
// この使い方の場合、ここまでする必要もないかもしれないけれど一応。
(function() {
  var ChromeDriver, By;
  var pathToChromeDriver, driver, searchBox;

  // Javaのimport相当。
  ChromeDriver = Java.type("org.openqa.selenium.chrome.ChromeDriver");
  By = Java.type("org.openqa.selenium.By");

  // chromedriver.exeへのパスをプロパティに設定。
  // chromedriver.exeが環境変数PATHに指定しているフォルダにあるなら省略できる。
  pathToChromeDriver = 'C:\\\\path\\to\\chromedriver.exe';
  java.lang.System.setProperty('webdriver.chrome.driver', pathToChromeDriver);

  // 実行内容は、
  //   Getting started - ChromeDriver - WebDriver for Chrome
  //   https://sites.google.com/a/chromium.org/chromedriver/getting-started
  // と同じ。
  // Chromeを起動して、Googleで"ChromeDriver"を検索して、Chromeを終了する。
  driver = new ChromeDriver();
  driver.get('http://www.google.com/xhtml');
  java.lang.Thread.sleep(5000);
  searchBox = driver.findElement(By.name('q'));
  searchBox.sendKeys('ChromeDriver');
  searchBox.submit();
  java.lang.Thread.sleep(5000);
  driver.quit();
}());

実行方法

コマンドプロンプトからjjs (nashornを起動するツール) を実行する。その際、-cpオプションでSelenium Standalone Serverをクラスパスに追加しておく。
> jjs -cp "C:\path\to\selenium-server-standalone-3.4.0.jar" nashorn-selenium.js

感想

もろもろの補完が効かないから、スクリプトを書くのが疲れる。けれど、IDE入れるなら環境を整えて、Javaから動かせばよいので、どちらの手間を惜しむかか。

References