MAGAZINE

ルーターマガジン

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

Windows上で稼働しているChromeにWSLから接続する

2023.09.15
Pocket

スクレイピングの最終形は実機自動操縦

スクレイピングには方式がいろいろありますが、最終形は普段使いのスマホの自動操縦や、普段使いのChromeの自動操縦となります。ChromeにはChrome Devtools Protocol という機能が備わっており、9222ポート経由で外部プロセスから操作することが可能です。Chrome Devtools Protocol を使うためのRubyのgemライブラリがchrome_remoteというライブラリです。

curl localhost:9222/json でアクセスすることで、ローカルホストのChromeに接続できたかどうかを確認できます。

以下の記事でchrome_remoteの解説をしています。

WindowsとWSL上のUbuntuは別マシン

大半の開発タスクはWSL上のUbuntuで実行できますが、さすがに普段使いのChromeはWindows上で動かしています。 WSL2からは仮想マシンとしてWSLが起動するため、WSL上でlocalhost:9222に接続しようとしても、Linux上のChromeに接続しようとしてしまいます。

解決策として、Windowsにsshdを入れて、WSLからのポートフォワードを実現します。

Windows上にsshdをインストール

以下Windowsにsshdをインストールして、WSLから接続するために手順です。 PSから始まるプロンプトはWindows側の管理者権限で起動したPowerShellターミナルで実行しています。 また、私のWindowsログインユーザがyugoyであるため、サンプルのyugoyは適宜自分のユーザ名に置き換えてください。

wingetを使ってsshdをインストール

PS C:\Users\yugoy> winget install --id=Microsoft.OpenSSH.Beta  -e

これでインストール完了

試しに起動してみる→失敗

PS C:\Users\yugoy> net start sshd
システム エラー 5 が発生しました。

アクセスが拒否されました。

ファイヤウォールの設定も必要です。

ファイヤウォール設定で22ポート(sshd)を開く

PS C:\Users\yugoy> netsh advfirewall firewall add rule name=sshd dir=in action=allow protocol=TCP localport=22
OK

sshdの起動と終了

PS C:\Users\yugoy> net start sshd
OpenSSH SSH Server サービスを開始します.
OpenSSH SSH Server サービスは正常に開始されました。

PS C:\Users\yugoy> net stop sshd

OpenSSH SSH Server サービスは正常に停止されました。

自動起動するオプションもありますが、常時起動してほしい訳では無いので手動で起動することにします。

sshdの設定ファイルを修正して公開鍵認証にする

Linuxでは設定ファイルは/etc配下ですが、Windowsに入るsshdはProgramData配下にあります。

C:\ProgramData\ssh\sshd_config

以下をコメントアウト

#Match Group administrators
#      AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

秘密鍵のみのログインを許可する

PasswordAuthentication no

ユーザディレクトリに公開鍵をセット

C:\Users\yugoy.ssh\authorized_keys

に自分の公開鍵をセットします。(Windows上のエディタでコピペして保存)

WSLからWindowsにssh接続してみる

WSLからWindowsに接続するにも、Windows側のIPアドレスを調べないといけません。WSLからみたときのWindowsのIPアドレスは以下のように調べます。

root@yugo:~#  ip route
default via 172.22.80.1 dev eth0 proto kernel
172.22.80.0/20 dev eth0 proto kernel scope link src 172.22.89.71

これで172.22.80.1がWindows側のIPということがわかったので、ユーザー名@IPアドレスで接続します。

root@yugo:~# ssh yugoy@172.22.80.1
Microsoft Windows [Version 10.0.22621.2134]
(c) Microsoft Corporation. All rights reserved.

yugoy@YUGO C:\Users\yugoy>

Windows側にログインできました。これはテスト接続なので、exitして接続を終了します。

WSLからWindowsへのポートフォワードをする

ssh接続が成功したので次はポートフォワードしてみましょう。 先程取得したWindowsのIPアドレス(今回は172.22.80.1)にポートフォワードで9222ポートを通します。

ssh -L 9222:127.0.0.1:9222 yugoy@172.22.80.1

上記の例では、WSLからWindowsにログインしながら、Windowsのローカルホストの9222ポートを、WSL側の9222ポートにフォワードしています。9222はchrome_remoteで接続するポートですね。

次にWSL上からlocalhostに接続してchromeのDevToolsに接続できるかどうかをみましょう。

root@yugo:~# curl localhost:9222/json
[ {
   "description": "",
   "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/C87088CE0F04FDDFEBC2D470EF3EB837",
   "faviconUrl": "https://calendar.google.com/googlecalendar/images/favicons_2020q4/calendar_6.ico",
   "id": "C87088CE0F04FDDFEBC2D470EF3EB837",
   "title": "株式会社ルーター - カレンダー - 2023年 9月 4日の週",
   "type": "page",
   "url": "https://calendar.google.com/calendar/u/1/r",
   "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/C87088CE0F04FDDFEBC2D470EF3EB837"
},...

こんな感じで、Windows上で起動してるchromeのタブの情報が返ってくるので成功です。

次にchrome_remoteでWSLからWindowsにアクセスできるかどうかの検証コードを実行します。

watch_chrome.rb

require 'chrome_remote'

chrome = ChromeRemote.client(logger: Logger.new($stdout))
p chrome.send_cmd 'Runtime.evaluate', expression: 'document.title'

実行結果です。Windows側のChromeのアクティブなタブのタイトルをWSLから接続してダンプしています。 INFOのログはChromeRemoteのライブラリが吐いてくれています。

$ ruby watch_chrome.rb
I, [2023-09-06T19:21:17.864188 #26439]  INFO -- : SEND ► {"method":"Runtime.evaluate","params":{"expression":"document.title"},"id":1}
I, [2023-09-06T19:21:17.888005 #26439]  INFO -- : ◀ RECV {"id":1,"result":{"result":{"type":"string","value":"chrome_remote\u3068\u3044\u3046\u9078\u629e\uff08\u8131Selenium\u5927\u4f5c\u6226\uff09 \u2013 \u682a\u5f0f\u4f1a\u793e\u30eb\u30fc\u30bf\u30fc"}}}
{"result"=>{"type"=>"string", "value"=>"chrome_remoteという選択(脱Selenium大作戦) – 株式会社ルーター"}}

とはいえここまでしてスクレイピングしないといけないことはめったにない

WSL2上にもchromeはインストールできるので、Windows上のchromeに接続する機会は滅多にありません。どうしてもWindows上のChromeでないと機能しないサイトでの対応となります。

ちなみにMacの場合は、普段使いのChromeもBashも同一マシンでうごいているため、こんな手間はかかりません。

Pocket

CONTACT

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