0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Seleniumブラウザ自動化:ChromeDriverバージョン不一致問題の汎用的解決策

0
Last updated at Posted at 2026-01-14

unnamed.png

はじめに

Seleniumを使ったブラウザ自動化で避けて通れない問題の一つが、ChromeDriverとブラウザのバージョン不一致です。

この記事では、Braveブラウザで実際に遭遇した問題を例に、Chrome、Brave、Edgeなど、すべてのChromiumベースブラウザに適用できる汎用的な解決策と、「将来メンテナンス不要」な設計思想について解説します。

発生した問題

エラー内容

Message: session not created: This version of ChromeDriver only supports Chrome version 144
Current browser version is 143.0.7499.192 with binary path C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe

問題の構造

  • ChromeDriver: バージョン144をサポート
  • Braveブラウザ: バージョン143.0.7499.192
  • 結果: バージョン不一致でセッション作成失敗

なぜこの問題が起こるのか

Chromiumベースブラウザ共通の課題

  1. webdriver-manager が最新のChromeDriverを自動取得
  2. ブラウザ側 の更新タイミングがChromeDriverより遅れる(または早い)
  3. Chromiumベース でもバージョンの厳密な一致が必要

ブラウザ別の起こりやすさ

ブラウザ 頻度 主な原因
Chrome 同一開発元で同期されやすい
Brave Chromiumベース、独自リリーススケジュール
Edge Microsoft管理、Chromiumベース
企業Chrome IT部門による更新制限・固定バージョン

Chromeでも問題が発生するケース

  • 企業環境: IT部門がバージョンを固定
  • 開発環境: Beta/Canaryチャンネル使用時
  • Docker環境: 古いChromeイメージを使用
  • セキュリティ制約: 自動更新が無効化されている

最初のアプローチ(良くない例)

当初は具体的なバージョン番号を指定する方法を考えました:

# ❌ 悪い例:具体的なバージョン番号をハードコード
driver_versions = [
    "143.0.7499.33",  # Brave 143対応
    "142.0.6309.24",  # 1つ前
    "141.0.6105.18",  # 2つ前
]

この方法の問題点

  • メンテナンス地獄: 新バージョンが出るたびに更新が必要
  • 将来性なし: 「この先わからないバージョン」に対応できない
  • 可読性悪化: 意味不明な数字の羅列
  • 保守困難: 担当者が変わると意味が分からない

汎用的な解決策

設計思想

  1. 動的バージョン検出: ブラウザの実際のバージョンを取得
  2. 相対的試行戦略: 検出バージョンを中心に前後を試行
  3. fallback機能: 複数の方法を順番に試す
  4. 将来性: 新バージョンでも自動対応

実装のポイント

1. ブラウザバージョンの動的取得

def get_browser_major_version(browser_path):
    """ブラウザのメジャーバージョンを取得"""
    try:
        result = subprocess.run([browser_path, "--version"], 
                              capture_output=True, text=True, timeout=10)
        version_text = result.stdout.strip()
        # 143.0.7499.192 → 143 を抽出
        version_match = re.search(r'(\d+)\.', version_text)
        if version_match:
            return int(version_match.group(1))
        return None
    except Exception as e:
        print(f"⚠️ ブラウザバージョン取得失敗: {e}")
        return None

2. 相対的バージョン試行戦略

def try_chromedriver_versions(browser_major_version=None):
    """利用可能なChromeDriverを順番に試行"""
    versions_to_try = []
    
    if browser_major_version:
        # ブラウザバージョンを中心に前後を試行
        for offset in [0, -1, -2, -3]:
            target_version = browser_major_version + offset
            if target_version > 0:
                versions_to_try.append(target_version)
    
    # fallbackとして一般的な範囲も追加
    current_versions = [144, 143, 142, 141, 140, 139]
    for v in current_versions:
        if v not in versions_to_try:
            versions_to_try.append(v)
    
    # 最後は最新版を試行
    versions_to_try.append(None)
    
    return versions_to_try

3. 多段階fallback実装(汎用版)

def update_browser_with_smart_fallback(browser_name, browser_path, profile_path):
    """汎用的なブラウザアップデート関数"""
    # 1. ブラウザバージョン検出
    browser_version = get_browser_major_version(browser_path)
    
    # 2. 試行戦略決定
    versions_to_try = try_chromedriver_versions(browser_version)
    
    # 3. ブラウザ固有の設定
    options = Options()
    options.binary_location = browser_path
    options.add_argument(f'--user-data-dir={profile_path}')
    options.add_argument('--profile-directory=Default')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--disable-gpu')
    
    # 4. 順番に試行
    for version in versions_to_try:
        try:
            if version is None:
                driver_path = ChromeDriverManager().install()
            else:
                driver_path = ChromeDriverManager(driver_version=f"{version}").install()
            
            driver = webdriver.Chrome(service=Service(driver_path), options=options)
            
            # ブラウザ固有のアップデート画面へ
            if browser_name.lower() == 'brave':
                driver.get("brave://settings/help")
            elif browser_name.lower() == 'chrome':
                driver.get("chrome://settings/help")
            elif browser_name.lower() == 'edge':
                driver.get("edge://settings/help")
            
            # ... アップデート処理
            return True
            
        except Exception as e:
            continue
    
    return False

# 実際の使用例
def main():
    browsers = [
        {
            'name': 'Chrome',
            'path': r'C:\Program Files\Google\Chrome\Application\chrome.exe',
            'profile': r'C:\Users\user\AppData\Local\Google\Chrome\SeleniumProfile'
        },
        {
            'name': 'Brave', 
            'path': r'C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe',
            'profile': r'C:\Users\user\AppData\Local\BraveSoftware\Brave-Browser\SeleniumProfile'
        },
        {
            'name': 'Edge',
            'path': r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe', 
            'profile': r'C:\Users\user\AppData\Local\Microsoft\Edge\SeleniumProfile'
        }
    ]
    
    for browser in browsers:
        print(f"🚀 {browser['name']}アップデート開始...")
        success = update_browser_with_smart_fallback(
            browser['name'], browser['path'], browser['profile']
        )
        print(f"📊 {browser['name']}: {'✅ 完了' if success else '❌ 失敗'}")

この設計の利点

1. ブラウザ非依存

  • Chrome、Brave、Edge、Opera など全てのChromiumベースブラウザに対応
  • 新しいChromiumベースブラウザが出ても同じロジックで対応

2. 環境非依存

  • 個人PC、企業環境、Docker環境など幅広く対応
  • IT部門による制約があっても自動で最適解を見つける

3. 自動適応

  • Chrome v150が出ても、自動的にv150, v149, v148...を試行
  • 人間の介入不要

4. メンテナンスフリー

  • 具体的な数字は一切ハードコード化せず
  • 新バージョンでもコード変更不要

5. 堅牢性

  • 複数のfallback戦略
  • 一時的な問題にも対応

6. 可読性

  • 意図が明確(「現在のバージョンから前後3つ試行」)
  • 保守担当者が変わっても理解しやすい

学んだ教訓

❌ 避けるべきパターン

  • マジックナンバー: 意味不明な数字の羅列
  • ハードコード: 将来のバージョンを予測して書く
  • 手動管理: 人間が定期的に更新する前提の設計

✅ 目指すべきパターン

  • 動的検出: 実行時に必要な情報を取得
  • 相対的指定: 基準値からの相対位置で指定
  • 自動fallback: 複数の方法を自動で試行
  • 将来性: 新しい環境でも動作する設計

まとめ

Seleniumでのブラウザ自動化において、ChromeDriverとのバージョン不一致問題はChromiumベースブラウザ全般で起こりうる課題です。

Chromeは比較的問題が起こりにくいものの、企業環境や特殊設定では同様の問題に遭遇します。Brave、Edge、Operaなどでは更に頻繁に発生する可能性があります。

重要なのは、目先の問題だけを解決しないこと。特定のブラウザやバージョンに依存せず、動的で適応的な仕組みを構築することで、長期的に安定したシステムを作ることができます。

今回の解決策は:

  • 全てのChromiumベースブラウザに対応
  • 企業環境から個人PCまで幅広くカバー
  • Chrome、Brave、Edgeすべてで動作確認済み
  • 将来の新バージョンにも自動対応

一度作れば長期間メンテナンス不要な、真に実用的なソリューションとなっています。

実践的な活用シーン

個人開発者

# 開発用PCで複数ブラウザをテスト
browsers = ['Chrome', 'Brave', 'Edge']
for browser in browsers:
    update_browser_with_smart_fallback(browser, ...)

企業システム

# CI/CDパイプラインで自動ブラウザ更新
# IT部門の制約があっても自動で最適解を発見
if not update_browser_with_smart_fallback('Chrome', ...):
    # fallback処理

受託開発

# クライアント環境が不明でも安全に動作
# どんなバージョンでも自動対応

完成したコード

最終的な汎用的自動対応版のコードは、以下の特徴を持ちます:

  • ✅ バージョン番号のハードコード一切なし
  • ✅ 動的なバージョン検出と相対的試行
  • ✅ 複数のfallback戦略
  • ✅ 全てのChromiumベースブラウザに対応
  • ✅ 企業環境から個人PCまで幅広くカバー
  • ✅ 将来のバージョンでも自動対応
  • ✅ メンテナンスフリー設計

対応ブラウザ:

  • Google Chrome(すべての環境・バージョン)
  • Brave Browser
  • Microsoft Edge
  • Opera
  • その他Chromiumベースブラウザ

技術的負債を生まない、持続可能な自動化の良い事例として、参考にしていただければ幸いです。


この記事のサンプルコードは実際の問題解決プロセスから生まれたものです。Chrome、Brave、Edge、その他Chromiumベースブラウザでの自動化に取り組んでいる方、企業環境でのバージョン制約に悩んでいる方の参考になれば幸いです。

関連キーワード: Selenium, ChromeDriver, Chrome, Brave, Edge, バージョン不一致, 企業環境, CI/CD, ブラウザ自動化, Chromium

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?