LoginSignup
1
1

exe化したPythonのChromeDriverManager().install()で発生するAttributeErrorの解決方法

Last updated at Posted at 2023-04-09

背景

pyinstallerでpythonファイル群をexe化したら、動いていたはずのアプリが動かない。
スタックトレースを確認したところ、ChromeDriverManager().install()でAttributeErrorが発生していた。

前提

ライブラリなど バージョン
webdriver-manager 3.8.5
pyinstaller 5.9.0
pyinstaller-hooks-contrib 2023.1
python 3.10.7

再現コード

error_rep.py
from webdriver_manager.chrome import ChromeDriverManager

if __name__ == '__main__':
    # オプション設定
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-extensions')
    options.add_argument('--proxy-server="direct://"')
    options.add_argument('--proxy-bypass-list=*')

    # ↓でエラー
    new_driver = ChromeDriverManager().install()

    service = Service(executable_path=new_driver)
    return webdriver.Chrome(service=service, options=options)

ソースが記述できたのでexe化

pyinstaller error_rep.py --onefile --noconsole

すると以下のエラーが発生

Traceback (most recent call last):
  File "error_rep.py", line 13, in main
  File "webdriver_manager\chrome.py", line 39, in install
  File "webdriver_manager\core\manager.py", line 30, in _get_driver_path
  File "webdriver_manager\core\download_manager.py", line 28, in download_file
  File "webdriver_manager\core\http.py", line 35, in get
  File "webdriver_manager\core\utils.py", line 289, in show_download_progress
  File "tqdm\std.py", line 1095, in __init__
  File "tqdm\std.py", line 1344, in refresh
  File "tqdm\std.py", line 1492, in display
  File "tqdm\std.py", line 347, in print_status
  File "tqdm\std.py", line 340, in fp_write
  File "tqdm\utils.py", line 71, in __getattr__
AttributeError: 'NoneType' object has no attribute 'write'

VSコードでは問題なく動くので「何もしてないのに壊れた!」という気持ち。

原因

このページによると、ChromeDriverManager().install()を呼び出した際にコンソール上にプログレスバーが表示されるらしい。
しかしexe化する際に--noconsoleオプションを指定しているためコンソールが画面上に表示されず、「プログレスバー出力する場所がありませんよー」的な状況らしい。

解決方法

プログレスバーを出力する場所を適当に指定すればokなのでソースを以下の通り修正する

error_rep.py
from webdriver_manager.chrome import ChromeDriverManager

if __name__ == '__main__':
    # オプション設定
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-extensions')
    options.add_argument('--proxy-server="direct://"')
    options.add_argument('--proxy-bypass-list=*')

    # 追加
    buffer = io.StringIO()
    sys.stdout = buffer
    sys.stderr = buffer

    new_driver = ChromeDriverManager().install()
    service = Service(executable_path=new_driver)
    return webdriver.Chrome(service=service, options=options)

再度pyinstallerでexe化したら行けた!

1
1
2

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
1
1