【Python】SeleniumをEXE化(PyInstaller等)するとブラウザが閉じない問題の原因と対策🧹✨

IT・テクノロジー

Seleniumで業務自動化をしていると、EXE化した途端にChrome(やDriver)のプロセスが残ることがあります😇💦
放置すると、PCが重くなる・メモリを食う・次回実行が不安定になる…など地味にダメージ大です⚠️

参考書籍

業務効率化に向けたおすすめの参考書になります。


まず結論:やることは3つだけ✅🔧

  1. driver.quit() を “必ず” 実行する(例外でも)
  2. close()quit() の違いを理解して使い分ける
  3. それでも残る時は 保険(atexit / 強制終了) を入れる ✅

quit() は「全ウィンドウ/タブを閉じ、ブラウザ・ドライバプロセスも終了」するのが基本動作です。


EXE化で起きやすい理由あるある🧩😵‍💫

EXE化(PyInstaller等)すると、次のような条件で「終了処理に到達しない」ことが増えます👇

  • 例外が起きて 終了処理(quit)まで行かない 💥
  • 途中で return / sys.exit() して finallyが走らない書き方 🌀
  • 例外処理が雑で、driver変数が未生成のまま終了 🙃
  • “裏で動く処理”(スレッド/外部プロセス)が残って 親が落ちても子が残る 👻

正攻法:driver.quit() を「必ず」通すテンプレ🧱✨

① いちばん強い:try / finally で閉じる🧰✅

from selenium import webdriver

driver = None
try:
    driver = webdriver.Chrome()
    driver.get("https://example.com")
    # ✅ ここに自動化処理を書く
finally:
    if driver is not None:
        driver.quit()
  • 例外が起きても finally は実行されるので、閉じ漏れが激減します🧹
  • Selenium公式の説明でも、quit を呼ばないと バックグラウンドプロセス等が残って問題になる旨が明記されています。

② “保険” に最適:atexit で終了時クリーニング🪄🔒

「何が起きても最後に掃除してほしい」用途なら atexit が便利です🧼
(※正常終了時に実行される“終了ハンドラ”)

import atexit
from selenium import webdriver

driver = webdriver.Chrome()

def cleanup():
    try:
        driver.quit()
    except Exception:
        pass

atexit.register(cleanup)

# ✅ 自動化処理...

落とし穴:close() では足りないことが多い⚠️🪟

close() は「今見てるタブ/ウィンドウだけ」😶‍🌫️

  • Seleniumの仕様上、close現在のウィンドウを閉じる動作です。
  • 一方 quit関連する全ウィンドウを閉じてセッションを終了します。

業務自動化の後処理は基本 quit() を選ぶのが安全です🔐


逆に「閉じない設定」を入れていない?😇🧨

Chromeのオプションで detach=True を入れていると、ドライバ終了後もブラウザが残る挙動になります🧲
(デバッグ用途では便利だけど、本番EXEでは事故りやすい)

from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("detach", True)  # ← これが原因になることも

✅ EXE配布・運用用途なら、基本は detachを外すのが無難です🙅‍♂️


それでも残るときの“最終手段”🧯💣(現場向け)

正攻法でも環境次第でプロセスが残るケースがあります(特に多重起動や拡張ツール併用など)😵
その場合は「PID管理 → 終了」を組み込むと安定します。

① “Driverを握ってるプロセス” を狙う🎯

  • 実行前後で chromedriver / chrome のPIDを記録
  • 終了時に残っていたら taskkill(Windows)で掃除🧹

※強制終了は諸刃なので、最後の最後にだけ使うのがおすすめです⚠️


EXE運用がラクになるコツ(業務で効く)📈✨

✅ タイムアウトを入れる⏱️

固まって quit に到達しない事故を減らします。

✅ ログを出す📝

「どこで止まったか」が分かると、閉じ漏れ原因を潰せます。

✅ 例外を握りつぶさない🙅

except: pass 連発だと、閉じ漏れが“隠れて”増殖します👻


まとめ:EXE化でも安定させる鉄板セット🧷✅

  • 終了処理は driver.quit() が基本close() だけだと残りやすい)
  • try / finally で quit を必ず通す
  • 保険に atexit(正常終了の掃除役)
  • detach=True は本番EXEでは外す(ブラウザが残る設定)

FAQ(よくある質問)❓😊

Q1. close() だけじゃダメ?🚪

close() は「今のタブ/ウィンドウだけ」を閉じます。セッションやプロセスが残ることがあるので、基本は quit() が安全です🧹

Q2. EXE化すると“たまに”しか起きないのはなぜ?🎲

例外の出方や実行タイミングがブレると、終了処理に到達したりしなかったりします💦
try/finally とログが入っていると原因特定が一気にラクになります📝✨

Q3. ブラウザを開いたままにしたい(デバッグしたい)🧪

detach=True を使うと、ドライバ終了後もブラウザを残せます。ただし運用EXEでは事故りやすいので、用途で切り替えがおすすめです🔁

Q4. atexit を入れたのに残ることがある…😢

atexit は「正常終了」で動く仕組みです。強制終了(クラッシュ/kill)だと走らない場合があります。
その場合は、タイムアウトやPID監視など“別の保険”も検討すると安定します🧯

Q5. 一番おすすめの実装は?🏆

まずは try/finally + driver.quit() が最優先です✅
次に保険として atexit を足すと、業務運用での事故率がグッと下がります🛡️

コメント

タイトルとURLをコピーしました