WSL上でSeleniumからWindows版Chrome使いたい時にRemoteWebDriver使うのが面倒なので、
LocalWebDriver風に扱えるようにProxyを作ってみました。

chromedriver-proxy-for-wsl | GitHub
https://github.com/takemikami/chromedriver-proxy-for-wsl

Local WebDriver、Remote WebDriver、
及び作成したプロキシを使った場合の3パターンの構成の違いは次の図のようになります。

chromedriver-proxy-for-wsl

各パターンの手順の違いを示した方が分かりやすいと思うので、
以降で順に説明していきます。

Local WebDriverの場合の手順

Local WebDriverを使う場合は、次のようなコードを実行する事になります。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

if __name__ == '__main__':
    driver = webdriver.Chrome(
        service=Service(executable_path="./chromedriver"),
        options=Options()
    )
    driver.get("http://www.google.com")
    driver.quit()

これをWSLで実行したい場合は、次の流れになります。

  • WSL上にChromeをインストール
  • WSL上にChromeWebDriverを入手して配置
  • WSL上で上記のコードを実行

特に問題は無いのですが、
WSLg上のChromeは動作が遅いのと、ちょっと不安定なのがストレスです。

Remote WebDriverの場合の手順

Remote WebDriverを使う場合は、次のようなコードを実行する事になります。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

if __name__ == '__main__':
    driver = webdriver.Remote(
        command_executor='http://※WindowHostのIPアドレス※:9515'
    )
    driver.get("http://www.google.com")
    driver.quit()

これをWSLで実行したい場合は、次の流れになります。

  • Windows上にChromeをインストール
  • Windows上にChromeWebDriverを入手して配置
  • Windows上でChromeWebDriverを実行、この際にWSLからアクセス出来るようにchromedriver.exe --allowed-ips 0.0.0.0のオプションを指定、セキュリティソフトのFirewallの許可設定も必要
  • WindowsホストのIPアドレスを調べる
  • 上記コードにWindowsホストのIPアドレスを指定する
  • WSL上で上記のコードを実行
  • Windows上でChromeWebDriverを停止

こちらは、ちょっと手続きが面倒です。
IPアドレスを調べたり、ChromeWebDriverを別に起動する必要があるので、特に面倒です。

この手順は、次のブログに細かく手順を書かれていたので参考にさせていただきました。

WSL2からWindowsのホストで起動したchromedriverに接続する | @ledsun blog
https://ledsun.hatenablog.com/entry/2022/06/09/230609

作成したプロキシを使った場合の手順

Remote WebDriverの場合の手順の手間を減らすことを考えたのが、 今回作成したプロキシの役割です。

実行するコードは、Local WebDriverを使う場合のコードです。

この場合の手順は次の流れになります。

  • Windows上にChromeをインストール
  • Windows上にChromeWebDriverを入手して配置
  • WSL上に今回作成したプロキシの実行ファイルを配置
  • WSL上にChromeWebDriverの格納先を記載した設定ファイルを配置
  • WSL上でLocal WebDriverを使う場合のコードを実行

※セキュリティソフトのFirewallの許可設定は別途必要

細かく手順を書いていきます。

Windows上にChromeをインストール

以下サイトの手順にしたがってインストール

Google Chrome
https://www.google.com/intl/ja_jp/chrome/

Windows上にChromeWebDriverを入手して配置

Chromeの「設定」→「Chromeについて」でバージョンを調べて、 次のサイトから、合致したバージョンのWindows版ドライバ(末尾がwin32のもの)をダウンロード。

Downloads | ChromeDriver
https://chromedriver.chromium.org/downloads

ダウンロードしたファイルを適当な場所に配置する。
以降の説明は、C:\tools\chromedriver_win32に配置したとして記載する。

WSL上に今回作成したプロキシの実行ファイルを配置

次のサイトから、プロキシの実行ファイルchromedriver_wsl.gzをダウンロードして、展開。

Releases | chromedriver-proxy-for-wsl | GitHub
https://github.com/takemikami/chromedriver-proxy-for-wsl/releases

chromedriver_wslは、chromedriverにリネームして、 Pythonのコードを実行する際のカレントディレクトリに配置。

WSL上にChromeWebDriverの格納先を記載した設定ファイルを配置

chromedriver_wslを置いたディレクトリと同じ位置に、 chromedriver_wsl_config.jsonと言う名称で以下の設定ファイルを作る。

{
  "chromedriver_bin": "/mnt/c/tools/chromedriver_win32/chromedriver.exe"
}

WSL上でLocal WebDriverを使う場合のコードを実行

以下のコード(再掲)を実行する。
Seleniumが必要なので、pip install seleniumでインストールしておくこと。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

if __name__ == '__main__':
    driver = webdriver.Chrome(
        service=Service(executable_path="./chromedriver"),
        options=Options()
    )
    driver.get("http://www.google.com")
    driver.quit()

今回作成したプロキシがLocalWebDriverのように振る舞い、
WindowsホストのIPアドレスを調べたり、ChromeWebDriverのアクセス許可や開始・終了をするので、
Remote WebDriver使うよりは楽にはなると思います。
また、Local WebDriver用にコードを書き換える必要も無いのも良いですね。

以上。