chromedriver のバージョンを Chrome に自動的に合わせる
はじめに
Selenium で GoogleChrome を操作する際は chromedriver をインストールしておく必要がありますが、このとき問題になるのが、chromedriver のバージョンを操作対象の GoogleChrome のバージョンに合わせる必要があるということです(経験上、メジャーバージョンが合っていれば良いようですが)。
通常 GoogleChrome は自動的にバージョンアップが行われますので、昨日まで動いていた Selenium が今日は動かないという事態が発生し、よく困っていました。
先に結論
これを解決するために、chromedriver のバージョンを 実行時に 合わせる(同期させる) Python ライブラリ chromedriver-binary-sync を作ってみました。
使い方
pip でインストールしてください。
pip install chromedriver-binary-sync
あとは、 スクリプト内でインポートして download
関数を呼ぶだけで、インストール済みの GoogleChrome のバージョンと一致する chromedriver をダウンロードします。
(既にファイルがあれば上書きします。)
import chromedriver_binary_sync
chromedriver_binary_sync.download()
引数を省略した場合、以下の挙動となります。
- 自動的にインストール済みの GoogleChrome を探す。
- これはほぼ
chromedriver-binary-auto
から引き継いだ動作です。
- これはほぼ
- chromedriver をカレントディレクトリにダウンロードする。
- スクリプトを pyinstaller で実行バイナリ化するケースも想定した動作です。
ダウンロード先を変更する場合
引数 download_dir
を指定してください。
chromedriver_binary_sync.download(download_dir='...')
ポータブル版 GoogleChrome を使用している場合 (Windows のみ)
引数 chrome_portable
を指定してください。
chromedriver_binary_sync.download(
chrome_portable=r'...\GoogleChromePortable\App\Chrome-bin\chrome.exe')
プロキシ環境下の場合
chromedriver のダウンロードには urllib.request
を使用しています。こちらが環境変数 http_proxy
https_proxy
no_proxy
を参照しますので、適宜設定してください。
作成した経緯
Python から Selenium を利用するスクリプトの為に chromedriver をインストールする場合は chromedriver-binary
を利用するのが簡単です。これを使うと、pip でインストールするだけで chromedriver のバイナリがダウンロードされ、インポートするだけでダウンロード先のディレクトリにパスを通してくれるので、とても簡単に chromedriver を使えるようになるという大変素晴らしいライブラリです。
しかし、これの難点は インストール時にバージョンを指定しなければならない という点です。GoogleChrome は勝手にバージョンが上がっていきますので、chromedriver のバージョンを手動で同期しなければなりません。
それを解決するための兄弟ライブラリとして chromedriver-binary-auto
があります。これを使うと、インストール済みの GoogleChrome のバージョンを自動的に認識して、適したバージョンの chromedriver をダウンロードしてくれます(インポートすればパスを通してくれる点は先程と同様です)。
これで解決かと思いきや、まだ問題があります。適したバージョンの chromedriver をダウンロードしてくれるのは pip によるインストール時 なのです。これでは、冒頭に書いた「昨日まで動いていた Selenium が今日は動かない」という事態を防ぐことはできません。インストール時ではなく 実行時 にバージョンを同期する仕組みが必要だったのです。
ということで作成したのが chromedriver-binary-sync
でした。
やっていることは同じなので、MIT ライセンスの恩恵を受け、コードは chromedriver-binary-auto をほぼ流用させていただきました。
Discussion