この記事は Selenium/Appium Advent Calendar 2018 の15日目の記事です。
こんにちは!
そう、そろそろネタ切れです。
よ、よろしくお願いします!!!
Processing
メディアアート方面の人にはおなじみの、ガーッと書いてグワーッと動かすやつです。
Web系の人には Processing.js や、後継の p5.js の方がおなじみかもしれませんね。それの元になったやつです。
ProcessingはJava互換のフレームワークですので、開発環境である PDE に所定の設定をするだけで至って普通にSeleniumのJava版クライアントを使えるようになります。
実際にやってみよう
準備
Seleniumの公式ダウンロードページ から、Java版のクライアントライブラリー 一式をダウンロードしましょう。この記事ではバージョン3.141.59を使います。
ダウンロードできたら、jarファイルをすべてライブラリーフォルダーに突っ込みましょう。macOSの場合は、 /Users/[自分のホームディレクトリー]/Documents/Processing3
がPDEの設定ディレクトリーになっていると思われます。その下の libraries
の下に selenium
さらにその下に library
とディレクトリを作り、その中にjarファイルをすべて置きます。
次に、インポートして利用するクライアントライブラリーのファイル名を変更して、 libraries
直下のディレクトリー名 selenium
と一致させます。こうしないと、PDEからクライアントライブラリーをインポートできません。
ここまでできたらPDEを起動しましょう。Seleniumクライアントが使えるようになります。
サンプルコード
大雑把には、次のサンプルのようなコードがPDE上で書けます。
おそらくProcessingでSeleniumを利用するときは、リアルタイムに取得したブラウザーのスクリーンショット画像を何かしら加工したりしなかったりして表示するのではないでしょうか。
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
WebDriver driver;
PImage pngImage;
void setup()
{
frameRate(15);
ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
driver = new ChromeDriver(options);
}
void dispose()
{
driver.quit();
println("disposed.");
}
void draw()
{
background(0);
if (pngImage != null)
{
image(pngImage, 0, 0);
}
if (frameCount % frameRate == 1)
{
thread("getScreenshotFromThread");
}
}
void getScreenshotFromThread()
{
driver.get("http://example.selenium.jp/reserveApp/");
File pngFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
pngImage = loadImage(pngFile.getAbsolutePath());
}
Processingで利用するときに注意するポイントは次のあたりかと思われます。
-
dispose()
を必ず書いて、Sketchの終了時にブラウザーとブラウザードライバーを必ず終了させましょう。- ただ、Processingで書いたSketchは往々にして動作不安定であり、
dispose()
できずに終了してしまうこともあります。開発中は、定期的にブラウザーとブラウザードライバーのプロセスの残りをkillall
などでお掃除しましょう。
- ただ、Processingで書いたSketchは往々にして動作不安定であり、
-
WebDriver.get()
やTakesScreenshot.getScreenshotAs()
をdraw()
の中で実行してしまうと、1フレームの実行にかかる時間が格段に増えてしまい、まともに描画できなくなります。thread()
などを利用して、別スレッドの中で実行するようにしましょう。 - ほんとうは
TakesScreenshot.getScreenshotAs()
の結果はbyte[]
で受け取りたいところですが、ProcessingのAPIの範囲ではPNG画像のバイト列をかんたんにビットマップに展開することができません。オーバーヘッドは非常に気になりますが、一度ファイルに出力してloadImage()
する方がシンプルなコードを書けるでしょう。- グリッチ画像を作りたい場合は
byte[]
で受け取りましょう。
- グリッチ画像を作りたい場合は
今回はここまで
次回は...誰かー! 誰か来てくれーーー!!!
Selenium/Appium Advent Calendar 2018はまだまだ君の挑戦を待っているぜ!