🦄

SeleniumなしでWebDriverを操作するには - Part1

2021/10/30に公開

SeleniumなしでWebDriverを操作するには

はじめに

対象読者

  • Web技術、特にJavaScriptやHTMLがわかる人
  • モダンな環境でブラウザオートメーションをやりたいが何からやったら良いかわからない人
  • 実はVBA × IE でオートメーションを実現しているがそろそろ変えていきたいと思っている人

検証環境

SurfaceBook(初代)
Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz 2.50
メモリ:8.00 GB
搭載OS:Windows 10 Pro 64bit
OSビルド:21H1 19043.1288

本題に入る前に情報を整理

WebDriver is 何

WebDriverとは

プラットフォームおよび言語に依存しないワイヤー プロトコルのW3C標準
このプロトコルにより、アウトプロセス プログラムは Web ブラウザーの動作をリモートで指示できます。

参考:Microsoft Edge開発者向けドキュメント WebDriver と他のソフトウェアの関係

つまりはブラウザの動作をプログラム等で命令することによってブラウザを操作することができる。
ここではこの動作のことを単に「ブラウザオートメーション」と定義して話します。

操作できるブラウザ is 何

Google Chrome、Microsoft Edge を始めとしたW3C標準の仕様に則ったブラウザが対象
ここでは単に「モダンブラウザ」と定義して話します。

今までのブラウザオートメーション

Windows環境でブラウザオートメーションをしようとするとIE×VBA、Selenium×Python などがあり
特にVBAはGoogle検索するとごまんと検索にヒットするかと思います。

ここではVBAを例に出して説明しますが
基本的にはComponent Object Model を利用してIEとExcelまたはAccessと連携することで
ブラウザスクレイピングを実現します。

ただし、このブラウザスクレイピングは
これからサポートを終了するIEを前提にしているモノですので
ブラウザのサポートが終了するならば、作りかえる必要があります。続

IE前提のブラウザオートメーションから脱却する為には

結論を言うと

暫定対応ならMicrosoft EdgeのIEモードを利用して従来通りのオートメーションを利用する。
恒久対応ならば

  • Microsoft公式が推奨するSeleniumを使う
  • WebView2を使う
  • 公式提供のWebDriverを使う
  • playwrightを使う
  • UiAutomation※を使う

※UiAutomation はブラウザ操作というよりネイティブUI に対する操作で扱える。
どちらかというとWebよりデスクトップアプリなどに使うもの。

余談

ソースコードを書かずにオートメーションを実現する方法もあります。
RPAは種類があるのでここで多くは語りませんが、Windows環境であれば
Power Automate Desktop を使ってみるのがありかと思います。

本題 WebDriverを使って自動化するには - 導入

WebDriverを使って自動化する場合は
まず、オートメーションで利用するブラウザとWebDriverのバージョンを合わせなければいけません。

各ブラウザのWebDriverはベンダーが提供しており例えば、Microsoft Edgeの場合は
Microsoftのサイトからダウンロードできます。

ちなみに個人開発したものですが
WebDriverとブラウザのバージョンをチェックして自動でダウンロードしてくれるツールを
dotNET Core 5 で作成しました。

DownloadWebDriver

参考:Microsoft Edge ドライバー
※Microsoft Edgeを操作するWebDriverのことをMicrosoft Edge ドライバーと言います。

本題 WebDriverを使って自動化するには - 利用

WebDriverはローカルホストで動作します。
ローカルホストに起動したWebDriverに対してリクエストを送ることでブラウザを操作することができます。

どのようなリクエストを送るとどのような動きをするかはW3Cのドキュメントに記載されています。

参考:W3C

とはいっても実際に読んで見ると難しいのでいくつか活用例を紹介します。

本題 WebDriverを使って自動化するには - 活用例

今回はMicrosoft Edge WebDriver(32bit)を利用します。
--help を指定して実行することで使い方が表示されます。


PS D:\edgedriver_win32> .\msedgedriver.exe --help
Options
  --port=PORT                     port to listen on
  --adb-port=PORT                 adb server port
  --log-path=FILE                 write server log to file instead of stderr, increases log level to INFO
  --log-level=LEVEL               set log level: ALL, DEBUG, INFO, WARNING, SEVERE, OFF
  --verbose                       log verbosely (equivalent to --log-level=ALL)
  --silent                        log nothing (equivalent to --log-level=OFF)
  --append-log                    append log file instead of rewriting
  --replayable                    (experimental) log verbosely and don't truncate long strings so that the log can be replayed.
  --version                       print the version number and exit
  --url-base                      base URL path prefix for commands, e.g. wd/url
  --readable-timestamp            add readable timestamps to log
  --enable-chrome-logs            show logs from the browser (overrides other logging options)
  --allowed-ips                   comma-separated allowlist of remote IP addresses which are allowed to connect to MSEdgeDriver

実行時はデフォルト時にhttp://localhost:9515で起動されます。
起動時のURLやポート番号は実行時に変更できます。

http://localhost:8080で起動する例

PS D:\edgedriver_win32> .\msedgedriver.exe --port=8080

Microsoft Edge ドライバーに対してリクエストを送る

前述のとおり
WebDriverに命令を出すには決まったエンドポイントに対してリクエストを送る必要があります。

次の節から具体的なリクエスト例について載せます。

Microsoft Edgeを起動

エンドポイント:http://localhost:9515/session
メソッド:POST
リクエスト用のJSON

{
    "capabilities":{}
}

戻り値

{
  "value": {
    "capabilities": {
      "acceptInsecureCerts": false,
      "browserName": "msedge",
      "browserVersion": "92.0.902.78",
      "ms:edgeOptions": {
        "debuggerAddress": "localhost:58808"
      },
      "msedge": {
        "msedgedriverVersion": "91.0.864.48 (27d934e7c76a9077a5bb7cc1512b894d360169ec)",
        "userDataDir": "C:\\Users\\username\\AppData\\Local\\Temp\\scoped_dir15040_1734679486"
      },
      "networkConnectionEnabled": false,
      "pageLoadStrategy": "normal",
      "platformName": "windows",
      "proxy": {},
      "setWindowRect": true,
      "strictFileInteractability": false,
      "timeouts": {
        "implicit": 0,
        "pageLoad": 300000,
        "script": 30000
      },
      "unhandledPromptBehavior": "dismiss and notify",
      "webauthn:extension:largeBlob": true,
      "webauthn:virtualAuthenticators": true
    },
    "sessionId": "b79db615f8fa18ce39528672f841bc6a"
  }
}

戻り値にあるsessionIdを今後の動作に使用します。

"sessionId": "b79db615f8fa18ce39528672f841bc6a"

URLを開く

指定のセッションIDに関連付けられたMicrosoft Edgeで指定のURLを開きます。

エンドポイント:http://localhost:9515/session/{sessionId}/url
メソッド:POST
リクエスト用のJSON

{
    "url":"{URL}"
}

ウィンドウを閉じる

指定のセッションIDに関連付けられたMicrosoft Edgeを閉じる。

エンドポイント:http://localhost:9515/session/{sessionId}
メソッド:DELETE
リクエスト用のJSON:なし

ウィンドウタイトルを取得

指定のセッションIDに関連付けられたMicrosoft Edgeからウィンドウタイトルを取得する。

エンドポイント:http://localhost:9515/session/{sessionId}/title
メソッド:GET

複数のウィンドウおよびタブがある場合は現在アクティブになっているウィンドウタイトルを取得します。

ウィンドウサイズと位置を指定

指定のセッションIDに関連付けられたMicrosoft Edgeのウィンドウを調整します。

エンドポイント:http://localhost:9515/session/{sessionId}/window/rect
メソッド:POST
リクエスト用のJSON

横の座標:200
縦の座標:200
画面の横サイズを500
画面の縦サイズを600 にしたいときは以下のJSON をリクエストで送る。

{
    "x":200,
    "y":200,
    "width":500,
    "height":600
}

ウィンドウサイズと位置を取得

指定のセッションIDに関連付けられたMicrosoft Edgeのウィンドウの情報を取得します。

エンドポイント:http://localhost:9515/session/{sessionId}/window/rect
メソッド:GET

ウィンドウハンドルを取得する

指定のセッションIDに関連付けられた
Microsoft Edgeのウィンドウの情報のハンドルを取得します。

エンドポイント:http://localhost:9515/session/{sessionId}/window/handles
メソッド:GET

ウィンドウ にスイッチ

エンドポイント:http://localhost:9515/session/{sessionId}/window
メソッド:POST
リクエスト用のJSON

{
    "handle":""
}

ウィンドウ を最大化

エンドポイント:http://localhost:9515/session/{sessionId}/window/maximize
メソッド:POST
リクエスト用のJSON

{
    "handle":""
}

エレメントIDを取得する

WebDriverでブラウザのエレメントを操作する場合はエレメント特有のIDが必要です。
特定のエレメントのIDを取得する場合は以下に示されるエレメントの特徴をPOSTで渡すことが重要になります。

using keyword
CSS selector css selector
Link text selector link text
Partial link text selector partial link text
Tag name tag name
XPath selector xpath

エレメントの操作はPart2に続く

Discussion