こんにちは!
わかりますか!!
わかりません!!!
わからないものは調べましょう、わかるようになります。
Seleniumでクリックするやりかた
Seleniumは、Webブラウザーに標準的なREST APIっぽいのがあって自動操作できたらいいな、という感じのフレームワークでして、たとえばクリックするときの処理はクライアント側としては /session/{session id}/element/{element id}/click
にHTTP POSTするだけです。詳細はW3C文書の説明をみてね!
https://www.w3.org/TR/webdriver/#element-click
ただ、一般的なWebブラウザーがもともとそんなAPIを持っているわけなくて、大方の場合はブラウザー固有の自動操作方式との相互変換を行ってくれるプロキシーを間にかますことになります。
chromedriver
とか geckodriver
とか呼ばれるアイツらのことですね。話のわかるヤツだ。
アイツらのクリックするやりかた
じゃあ、そのアイツらがやっている「ブラウザー固有の実装」とやらでは、クリックはどうやってるんでしょうね?
わかりますか? わかりません!! 調べてみましょう!!!
オープンソースのものは、詳細に調べることができます。
chromedriver
Chrome DevTools Protocolの Input.dispatchMouseEvent で、 mousePressed
と mouseReleased
を順に投げているだけです。
https://cs.chromium.org/chromium/src/chrome/test/chromedriver/chrome/web_view_impl.cc?sq=package:chromium&dr=C&l=408
Input.dispatchMouseEvent
を受け取ったChrome側では、最終的にはBlinkのマウスイベント処理を呼び出しているようです。
geckodriver
Marionette Protocolで clickElement
を投げているだけです。
https://github.com/mozilla/geckodriver/blob/v0.20.0/src/marionette.rs#L1090
clickElement
を受け取ったFirefox側では、最終的には clickイベント を発生させているだけのようです。
IEDriverServer
デフォルトではWindowsのネイティブAPI SendInput で MOUSEEVENTF_LEFTDOWN
と MOUSEEVENTF_LEFTUP
を送信しています。
https://github.com/SeleniumHQ/selenium/blob/master/cpp/iedriver/CommandHandlers/ClickElementCommandHandler.cpp#L86-L87
capabilitiesで nativeEvent
をfalseにすると動作が変わり、JavaScriptで clickイベント を発生させるようになるようです。
https://github.com/SeleniumHQ/selenium/blob/master/cpp/iedriver/CommandHandlers/ClickElementCommandHandler.cpp#L163-L167
jBrowserDriver
JavaFXの方のRobotクラス の mousePress
と mouseRelease
を実行しているだけのようです。
https://github.com/MachinePublishers/jBrowserDriver/blob/master/src/com/machinepublishers/jbrowserdriver/Robot.java#L520-L521
やりかたはいろいろあっていい
オープンソースのものだけでも、やりかたは千差万別であることがわかります。でも、インターフェースとしてのWebDriverは規格化され揃っているので、ブラウザ側の実装の違いは隠蔽され意識しなくてもいいようになっています。
WebDriver規格に準拠していればいい、というところを活かして、もっとブラウザドライバ側の実装に多様性が生まれても良いよね、と最近思い始めています。
例えば、Internet Explorerに関してです。ほんとうに厳密な意味でユーザー操作をエミュレートしたいのか、単に Trident でのレンダリング結果を得たいのか、どうにかしてヘッドレス動作させたいのか、などなど、本来ニーズは様々にあるかと思われる一方で、IEDriverServerだけではすべてのニーズに答えられていないのかもしれません。
実際、SeleniumからIEを扱うときにヘッドレス動作させたい、という人向けに、WindowsのCreateDesktop APIを利用した仮想デスクトップでヘッドレス風に実装してみた Headless Selenium for Windows なんてものも作る人があらわれています。私はこの実装だけでは不足があると思っていますが、考え方の方向性としてはとても良くて、もっとこういうアプローチを取れる人が増えると良いなと思っています。
これじゃ足りないよな、というところに対して、なんとなく主語が大きくなってSeleniumダメだよねという結論に終わるのでなく、様々なアイディアが形になっていくことが当たり前になっていくと良いですね!