[go: up one dir, main page]
More Web Proxy on the site http://driver.im/

【Selenium】ChromeDriver自動更新で楽する方法【Python】

- Python -
2024.02.13
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つの手段があります。状況によりどちらか選びましょう。

  1. 最新版(4.6以上)へ更新 → コード書き換え
  2. 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の自動更新が実現できます。

以下、導入手順です。

  1. webdriver-managerをインストール
  2. 既存コードを書き換え

▼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つの手段があります。状況によりどちらか選びましょう。

  1. 最新版(4.6以上)へ更新 → コード書き換え
  2. 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の自動更新が実現できます。

以下、導入手順です。

  1. webdriver-managerをインストール
  2. 既存コードを書き換え

▼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()

と書くだけなので、ぜひお試しください。

▼体型的なスクレイピング学習におすすめ

技術評論社Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド
Amazonで見る ≫
↑TOP