【Selenium】ChromeDriver自動更新で楽する方法【Python】
Python × Seleniumで、ChromeDriverのバージョンを気にしたり、手動ダウンロードする手間をゼロにしましょう。
【Windows・Mac共通】
Seleniumバージョン4.6以上ならこれ↓だけでOK。
Pythonfrom selenium import webdriver
driver = webdriver.Chrome()
※ 4.6〜4.10だと動かず最新版へ更新必要な場合あり
Selenium 4.5以下の場合、下記のどちらか
- Seleniumを最新版へ更新して上記記法に書き換え
- 更新できないなら、"webdriver-manager"を使って書き換え
Selenium 4.6から、Selenium自体にChromeDriver自動更新機能「Selenium Manager」が搭載されたことで、このシンプルな記述だけで済むようなりました。
ChromeDriver自動更新といえば「webdriver-managerをインストール」のみ紹介する記事が多いですが、Selenium 4.6以上ならwebdriver-managerを使う必要なし。
Selenium Managerの技術的な仕組みなどは他へ譲るとして、本記事はChromeDriver自動更新の実現方法のみにフォーカスします。
参考selenium.dev:Introducing Selenium Manager
!注意!
以下両方満たすかたがwebdriver-managerを使うと回避困難なエラーが出ます。
- Windowsを使っていて、
- ChromeDriverを利用したプログラムを4つ以上同時起動しうる環境
GitHubでissue報告があり、ぼく自身もタスクスケジューラで4つ以上起動していて直面し苦労したエラー。
関連記事Python Selenium PermissionError: [WinError 5] アクセスが拒否されました 解決法
このエラーは、Selenium最新版へ更新する方法なら回避できるので、webdriver-managerを採用する場合はご注意を。
ー もくじ ー
Python Selenium ChromeDriverの自動更新 準備編
現在どのSeleniumバージョンを利用しているかによって、対応が少しずつ異なります。
pip show seleniumでまず現バージョンをチェックしてみてください。
> pip show selenium
Name: selenium
Version: 3.141.0
Summary: Python bindings for Selenium
Home-page: https://github.com/SeleniumHQ/selenium/
Author: UNKNOWN
Author-email: UNKNOWN
License: Apache 2.0
Location: /usr/local/lib/python3.9/site-packages
Requires: urllib3
Required-by: PyPasser
現Seleniumのバージョンがどれかによって手順を分けて書いていきます。
Selenium 4.6以上を使っている場合
既存コードのわずかな書き換えのみなので10秒で終わります。
今までこんなふうに、executable_pathを指定するゴテゴテした書き方をしていた場合、
BEFOREfrom selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
service = ChromeService(executable_path="./drivers/chromedriver.exe")
driver = webdriver.Chrome(service=service)
こう↓するだけです。
AFTERfrom selenium import webdriver
driver = webdriver.Chrome()
ヘッドレスモード実行など、optionsを指定する場合は今まで通り。
AFTERfrom selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)
これで実行してみて、無事にChromeが起動すれば成功です。
(エラーが出てしまう場合は次の章へ...)
webdriver.Chrome()とするだけで、裏側でSelenium Managerが自動的に適切なドライバーをダウンロードするような動きになっています(すでに存在する場合、キャッシュから読み込まれる)。
今後、ChromeDriverのバージョンを意識することはありません。
ちなみに:
'--headless'ではなく'--headless=new'と書くことで、ヘッドレスChromeの挙動がヘッドフルChrome(=通常のブラウザ)でアクセスする環境に限りなく近くなるとのこと。
参考
developer.chrome.com: 2023年2月22日公開記事
Chrome’s Headless mode gets an upgrade: introducing --headless=new
4.6〜でエラーが出る=最新版へ更新して解決
seleniumバージョン 4.6〜4.10を使っているのに、以下のように「chromedriverのパスを指定しろ」エラーになってしまう。
▼selenium 4.6実行例
> python test-selenium.py
thread 'main' panicked at 'Downloaded file cannot be uncompressed (xml extension)', src/files.rs:46:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
・・・省略・・・
raise WebDriverException(f"Unsuccessful command executed: {args}")
selenium.common.exceptions.WebDriverException: Message: Unsuccessful command executed: ('/usr/local/lib/python3.9/site-packages/selenium/webdriver/common/macos/selenium-manager', '--browser', 'chrome')
・・・省略・・・
During handling of the above exception, another exception occurred:
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://chromedriver.chromium.org/home
こんなときは、以下コマンドでseleniumを最新版へ更新すれば解決するはずです。
pip install -U selenium
Selenium Managerはバージョン4.6から搭載された機能ですが、4.6でも環境によって動く・動かないがあるようです。
実際、ぼくは4.6〜4.10まで上記(と似た)エラーとなり、4.11から解消されました。
Selenium 4.0 〜 4.5を使っている場合
2つの手段があります。状況によりどちらか選びましょう。
- 最新版(4.6以上)へ更新 → コード書き換え
- webdriver-managerを使って書き換え
方法1. 最新版へ更新 → コード書き換え
以下、Seleniumを更新できる場合の手順です。
▼1. Selenium更新
これでSeleniumが最新版へ更新されます。
pip install -U selenium
> pip install -U selenium
Requirement already satisfied: selenium in /usr/local/lib/python3.9/site-packages (4.1.4.)
Collecting selenium
・・・省略・・・
Uninstalling selenium-4.1.4:
Successfully uninstalled selenium-4.1.4
Successfully installed selenium-4.12.0
▼2. コード書き換え
「Selenium 4.6以上を使っている場合」章を参考にコードを書き換えてください。
その後、無事にChromeが起動すれば成功、終わりです。
方法2. webdriver-managerを使う書き換え
記事冒頭でも書きましたが、以下両方満たすかたがwebdriver-managerを使うと回避困難なエラーにハマるのでご注意。
- Windowsを使っていて、
- ChromeDriverを利用したプログラムを4つ以上同時起動する可能性がある
何らか事情があってSeleniumバージョン更新ができない場合、webdriver-managerというライブラリを使うことでChromeDriverの自動更新が実現できます。
以下、導入手順です。
- webdriver-managerをインストール
- 既存コードを書き換え
▼1. インストール
pip install webdriver-manager
> pip install webdriver-manager
Collecting webdriver-manager
Obtaining dependency information for webdriver-manager from https://files.pythonhosted.org/packages/19/5a/a16653bfce685c9832217d377f52065351eeac9862e44e2996cd81f3bb4d/webdriver_manager-4.0.0-py2.py3-none-any.whl.metadata
Using cached webdriver_manager-4.0.0-py2.py3-none-any.whl.metadata (11 kB)
Requirement already satisfied: requests in /usr/local/lib/python3.9/site-packages (from webdriver-manager) (2.26.0)
Requirement already satisfied: python-dotenv in /usr/local/lib/python3.9/site-packages (from webdriver-manager) (1.0.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.9/site-packages (from webdriver-manager) (23.0)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/site-packages (from requests->webdriver-manager) (1.26.16)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/site-packages (from requests->webdriver-manager) (2022.12.7)
Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.9/site-packages (from requests->webdriver-manager) (2.0.4)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/site-packages (from requests->webdriver-manager) (2.10)
Using cached webdriver_manager-4.0.0-py2.py3-none-any.whl (27 kB)
Installing collected packages: webdriver-manager
Successfully installed webdriver-manager-4.0.0
Successfully installed...と表示されればOKです。
▼2. コード書き換え
既存コードがこうだったとして...
BEFOREfrom selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
service = ChromeService(executable_path="./drivers/chromedriver.exe")
driver = webdriver.Chrome(service=service)
こう↓します。
AFTERfrom selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
参考GitHub:webdriver-manager README
これで実行してみて、無事にChromeが起動すれば成功、終わりです。
ちなみに:
webdriver-managerを新しくインストールして使う場合、Google Chromeのバージョンが116.x以上であることを確実にしてください。
Selenium 3.xを使っている場合
2つの手段があります。状況によりどちらか選びましょう。
- 最新版(4.6以上)へ更新 → コード書き換え
- webdriver-managerを使う書き換え
方法1. 最新版へ更新 → コード書き換え
以下、Seleniumを更新できる場合の手順です。
▼1. Selenium更新
これでSeleniumが最新版へ更新されます。
pip install -U selenium
> pip install -U selenium
Collecting selenium
Downloading selenium-4.12.0-py3-none-any.whl (9.4 MB)
・・・省略・・・
Uninstalling selenium-3.141.0:
Successfully uninstalled selenium-3.141.0
Successfully installed certifi-2023.7.22 cffi-1.15.1 exceptiongroup-1.1.3 h11-0.14.0 outcome-1.2.0 pycparser-2.21 pysocks-1.7.1 selenium-4.12.0 sniffio-1.3.0 sortedcontainers-2.4.0 trio-0.22.2 trio-websocket-0.10.3 urllib3-2.0.4 wsproto-1.2.0
▼2. コード書き換え①
selenium 3と4ではfind_element系メソッドの記法が少し違うため、そのまま実行するとエラーが出てしまいます。
BEFORE → AFTERへ書き換えましょう。Byインポートを忘れずに。
Python# BEFORE
find_element_by_id("id")
find_element_by_name("name")
find_element_by_xpath("xpath")
find_element_by_link_text("link text")
find_element_by_partial_link_text("partial link text")
find_element_by_tag_name("tag name")
find_element_by_class_name("class name")
find_element_by_css_selector("css selector")
# AFTER
from selenium.webdriver.common.by import By
find_element(By.ID, "id")
find_element(By.NAME, "name")
find_element(By.XPATH, "xpath")
find_element(By.LINK_TEXT, "link text")
find_element(By.PARTIAL_LINK_TEXT, "partial link text")
find_element(By.TAG_NAME, "tag name")
find_element(By.CLASS_NAME, "class name")
find_element(By.CSS_SELECTOR, "css selector")
参考selenium-python.readthedocs.io:Locating Elements
▼2. コード書き換え②
次は、ChromeDriverの初期化部分を書き換えます。
既存コードがこうだったとして...
BEFOREfrom selenium import webdriver
driver = webdriver.Chrome('./drivers/chromedriver.exe')
こう↓します。引数で渡していたパスを消すだけ。
AFTERfrom selenium import webdriver
driver = webdriver.Chrome()
chromedriver_binaryをインポートしていた場合、不要なので削除してOKです。
ヘッドレスモード実行など、optionsを指定する場合は今まで通り。
AFTERfrom selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)
これで実行してみて、無事にChromeが起動すれば成功です。
今後、ChromeとChromeDriverのバージョンを意識することはありません。
方法2. webdriver-managerを使う書き換え
記事冒頭でも書きましたが、以下両方満たすかたがwebdriver-managerを使うと回避困難なエラーにハマるのでご注意。
- Windowsを使っている
- ChromeDriverを利用したプログラムを4つ以上同時起動する可能性がある
何らか事情があってSeleniumバージョン更新ができない場合、webdriver-managerというライブラリを使うことでChromeDriverの自動更新が実現できます。
以下、導入手順です。
- webdriver-managerをインストール
- 既存コードを書き換え
▼1. インストール
pip install webdriver-manager
> pip install webdriver-manager
Collecting webdriver-manager
Obtaining dependency information for webdriver-manager from https://files.pythonhosted.org/packages/19/5a/a16653bfce685c9832217d377f52065351eeac9862e44e2996cd81f3bb4d/webdriver_manager-4.0.0-py2.py3-none-any.whl.metadata
・・・省略・・・
Successfully installed webdriver-manager-4.0.0
Successfully installed...と表示されればOKです。
▼2. コード書き換え
既存コードがこうだったとして...
BEFOREfrom selenium import webdriver
driver = webdriver.Chrome('./drivers/chromedriver.exe')
こう↓します。
AFTERfrom selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
参考GitHub:webdriver-manager README
ヘッドレスモード実行などoptionsを指定する場合は、以下4, 5, 6行目のようにwebdriver.Chrome()にoptions引数を放り込むだけです。
Python(ヘッドレスモードで実行)from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
これで実行してみて、無事にChromeが起動すれば成功、終わりです。
ちなみに:
webdriver-managerを新しくインストールして使う場合、Google Chromeのバージョンが116.x以上であることを確実にしてください。
まとめ:自動更新はSelenium Managerに任せるのが一番ラク
webdriver-managerで、本記事冒頭で書いた不具合が起きたことで、
このままwebdriver-manager使い続けるのツラい...
となったのが、そもそもSelenium 4.6からSelenium自体にドライバー自動更新する機能「Selenium Manager」が搭載されたことを知ったキッカケでした。
Selenium 4.6のリリースは2022年11月4日で、もうかなり経っています。
にも関わらず、今はもうdriver = webdriver.Chrome()だけでOKだよ、と書いている記事が少ない気がしているので、
現在Selenium 4.6以上を使っているのに、ChromeDriverをダウンロードしてきてこのように↓パスを書いて運用しているかたがいるのではないか...?と思いました。
Pythonservice = ChromeService(executable_path="./drivers/chromedriver.exe")
driver = webdriver.Chrome(service=service)
また、これまではChromeDriver自動更新=webdriver-managerをインストールして使うというのが定番でしたが、これも不要になりました。
記事中で何度も何度も書いたことですが、Seleniumを最新に更新さえすれば
driver = webdriver.Chrome()
と書くだけなので、ぜひお試しください。
▼体型的なスクレイピング学習におすすめ