MAGAZINE

ルーターマガジン

クローリング/スクレイピング

websockets-cliでchromeを自動操縦しクラッシュさせる

2023.09.21
Pocket

弊社ではseleniumやchrome_remoteなどあらゆる手法で、chromeを自動操縦しております。そのような開発風景の1シーンとして、ちょっとしたテストをしたい、例えばCLIでchromeのクラッシュを再現させたいという需要が生じることがあります。 そんな需要にお答えして今回は、

  1. CLIでchromeを自動操縦する
  2. CLIでchromeのクラッシュを再現させる

の2本立てでお送りいたします。 また、本記事での実行環境はubuntuのbashシェルを想定します。

CLIでchromeを自動操縦する

seleniumやchromeremoteなどのライブラリは全て、chrome debugging portとwebsocket通信をしてchromeの操縦を実現しています。なればこそ、chrome debugging portとの通信をCLIで実現すれば良いのです。 世の中のwebsocket通信のCLIクライアントは様々に存在しますが、今回はwebsockets-cliで実装します。

  1. google-chromeを起動する
$ google-chrome --remote-debugging-port=9222
  1. websocketに利用できるエンドポイントを確認する
$ curl localhost:9222/json
[ {
   "description": "",
   "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/ABC469B501246CD1FFECF92179A20385",
   "id": "ABC469B501246CD1FFECF92179A20385",
   "title": "New Tab",
   "type": "page",
   "url": "chrome://newtab/",
   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/ABC469B501246CD1FFECF92179A20385"
}, {
   "description": "",
   "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/807CE22EA8FB832DDB0E193D3189A6AF",
   "id": "807CE22EA8FB832DDB0E193D3189A6AF",
   "parentId": "ABC469B501246CD1FFECF92179A20385",
   "title": "chrome-untrusted://new-tab-page/one-google-bar?paramsencoded=",
   "type": "iframe",
   "url": "chrome-untrusted://new-tab-page/one-google-bar?paramsencoded=",
   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/807CE22EA8FB832DDB0E193D3189A6AF"
} ]
  1. 返されたJSONの配列の中で "type": "page", となっている要素の webSocketDebuggerUrl の値をwsコマンドに渡す

複数タブがある場合は複数要素になるので、操縦したいタブのwebSocketDebuggerUrl を渡します。

$ ws text ws://localhost:9222/devtools/page/ABC469B501246CD1FFECF92179A20385 '{"method": "Page.navigate", "params": {"url":"https://example.com"}, "id": 1}'
Sent 77.0 B of data over the wire.

このコマンドで https://example.com にページ遷移できます。

CLIでchromeのクラッシュを再現させる

ここまでページ遷移するmethodを例として扱ってきましたが、chrome devtools protocolを参照して応用すれば、クリックやスクロールからcookie削除、ネットワーク監視まであらゆる機能が実装可能となります。

chromeのクラッシュについてもchrome devtools protocolPage.crashでメソッドが用意されています。

wsコマンドに渡すJSONを変えた上で、先と同様に以下のように webSocketDebuggerUrl を埋め込んで実行すると

$ ws text ws://localhost:9222/devtools/page/474A5132889A59E33FEF431B87FB707B '{"method": "Page.crash", "id": 1}'
Sent 33.0 B of data over the wire.

以下のようなクラッシュが確認できます。

おまけ:jqコマンドを使ってワンライナーにする

wsコマンドにエンドポイントを埋め込む処理をjqコマンドを使って無理矢理ワンライナーにすると以下になります。複数タブがある場合は1つ目のタブを選択します。

$ ws text $(curl localhost:9222/json | jq -r '[.[] | select(.type == "page")][0].webSocketDebuggerUrl') '{"method": "Page.navigate", "params": {"url":"https://example.com"}, "id": 1}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1243  100  1243    0     0   202k      0 --:--:-- --:--:-- --:--:--  202k
Sent 77.0 B of data over the wire.

chrome devtools protocolは便利

chrome devtools protocol は、ブラウザ操縦でよく使われるseleniumよりもchromeに近いレイヤーであるため、基本的にseleniumで出来てchrome devtools protocol に出来ないことは無いと考えて良いと思います。むしろ今回のクラッシュのようなseleniumでは実装が困難なものが簡単に出来てしまうケースもあります。もちろんケースによって一長一短がありますが、エンジニアであればより多くの選択肢を持っておきたいものですね。

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから