Pythonでのブラウザ自動化において、Seleniumは非常に強力なツールとして定着しています。
しかし、スクリプトの実行後にブラウザが閉じなかったり、タスクマネージャーにバックグラウンドプロセスが残ったりするトラブルに遭遇したことはないでしょうか。
これらの問題は、主にclose()メソッドとquit()メソッドの使い分けが正しく行われていないことに起因します。
リソースの浪費を防ぎ、安定した自動化環境を構築するためには、終了処理のメカニズムを正確に理解することが不可欠です。
本記事では、Python Seleniumにおける終了メソッドの決定的な違いと、プロセスを残さないための実装手法を詳しく紹介します。
Seleniumにおける終了処理の重要性
ブラウザの自動操作を行う際、プログラムが終了してもブラウザのウィンドウがデスクトップに残ってしまうことがあります。
これは単に見栄えが悪いだけでなく、コンピュータのメモリやCPUリソースを継続的に消費し続ける原因となります。
特にサーバー環境やCI/CDパイプラインでスクリプトを実行する場合、残留したプロセスが積み重なるとシステム全体の動作を停止させる恐れがあります。
2026年現在のモダンなWeb開発環境では、ブラウザの多機能化に伴い、1つのプロセスが消費するリソース量も増大しています。
そのため、スクリプトの最後で確実なクリーンアップを行うことが、プロフェッショナルなコードを書く上での最低条件となります。
close()メソッドの特徴と挙動
close()メソッドは、現在WebDriverがフォーカスを当てている「アクティブなウィンドウ」または「タブ」を閉じるためのコマンドです。
現在のアクティブウィンドウのみを閉じる
もしブラウザで複数のタブを開いている状態でclose()を実行すると、現在操作対象となっているタブだけが閉じられます。
他のタブやウィンドウはそのまま残り、WebDriverのセッション自体も継続されます。
このため、特定のポップアップウィンドウを閉じた後に元のウィンドウで操作を続けたい場合に適しています。
ブラウザプロセスは終了しない場合がある
重要な点として、close()はWebDriver全体のプロセスを終了させるものではないということが挙げられます。
もし開いているタブが1つだけであっても、close()を実行しただけでは、バックグラウンドで動作しているドライバ(chromedriverなど)が残り続けることがあります。
これが「スクリプトは終わったのにタスクマネージャーにプロセスが残る」という現象の主な要因の一つです。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
# アクティブなウィンドウを閉じる(プロセスは残る可能性がある)
driver.close()
quit()メソッドの特徴と挙動
一方で、quit()メソッドは、そのWebDriverセッションに関連するすべてのウィンドウを閉じ、ドライバプロセスを完全に終了させます。
セッション全体の破棄
quit()を呼び出すと、内部的にはブラウザの終了信号を送り、さらに実行ファイル(chromedriverなど)のプロセスを安全に停止させます。
これにより、使用していた一時プロファイルやメモリキャッシュも適切に解放されるようになります。
自動化処理の最後に呼び出すべきなのは、原則としてこのquit()メソッドです。
リソース解放の確実性
quit()は、OSレベルでのプロセス管理においてもクリーンな状態を保つのに役立ちます。
Pythonのスクリプトが正常に終了する場合、quit()を明示的に呼ぶことで、ゾンビプロセスの発生を抑制できます。
「ブラウザを閉じる」という目的であれば、常にquit()を優先して使用することを推奨します。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
# すべてのウィンドウを閉じ、ドライバプロセスも終了させる
driver.quit()
closeとquitの違いを比較する
ここで、2つのメソッドの違いを整理して比較表にまとめます。
| 機能 | close() | quit() |
|---|---|---|
| 対象範囲 | 現在アクティブなウィンドウ/タブのみ | セッションに関連するすべてのウィンドウ |
| ドライバプロセス | 原則として終了しない | 完全に終了・破棄する |
| 主な用途 | 特定のタブを閉じて操作を続ける場合 | 全処理を終えてリソースを解放する場合 |
| 推奨度 | 状況に応じて使用 | 自動化の終了時に必須 |
なぜプロセスが残ってしまうのか
quit()を記述しているにもかかわらず、プロセスが残ってしまうケースも存在します。
その背景には、プログラムの異常終了やドライバの設計上の問題が隠れています。
エラー発生による処理の中断
スクリプトの途中で例外(エラー)が発生すると、後続のdriver.quit()まで処理が到達しません。
これにより、ブラウザが立ち上がったままの状態になり、プロセスが放置されることになります。
デバッグ中や不安定なWebサイトを操作しているときには、特にこの現象が頻発します。
WebDriverとブラウザのバージョンの不一致
WebDriverのバージョンとブラウザのバージョンが乖離していると、終了信号が正しく伝わらないことがあります。
2026年現在は「WebDriver Manager」などの自動管理ツールが標準的に使われていますが、手動でバイナリを配置している場合は注意が必要です。
ドライバが「終了したつもり」になっても、ブラウザ側がプロセスを維持し続けてしまうデッドロックが発生することがあります。
プロセス残留を防ぐ正しい実装方法
ここからは、実務でプロセスを絶対に残さないための具体的なコーディング手法を解説します。
try-finally構文による確実な終了
最も基本的かつ強力な方法は、Pythonのtry-finally構文を利用することです。
tryブロックの中でメインの処理を行い、何があっても必ず実行されるfinallyブロックにquit()を記述します。
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
# ここに様々な自動化処理を記述
print(driver.title)
except WebDriverException as e:
print(f"エラーが発生しました: {e}")
finally:
# エラーが発生しても必ず実行される
if driver:
driver.quit()
print("ブラウザとプロセスを正常に終了しました。")
Example Domain
ブラウザとプロセスを正常に終了しました。
withステートメント(コンテキストマネージャ)の活用
Python 3.10以降や最新のSelenium 4系以降では、withステートメントを用いた記述も一般的です。
withブロックを抜ける際に自動的に終了処理が行われるため、quit()の書き忘れを防ぐことができます。
ただし、Seleniumの標準的なwebdriver.Chrome()などは直接withに対応していない場合があるため、ラッパークラスを作成するか、特定のライブラリを利用することが推奨されます。
from selenium import webdriver
# コンテキストマネージャとして振る舞うコード例
class SeleniumSession:
def __enter__(self):
self.driver = webdriver.Chrome()
return self.driver
def __exit__(self, exc_type, exc_val, exc_tb):
if self.driver:
self.driver.quit()
with SeleniumSession() as driver:
driver.get("https://example.com")
print(driver.title)
# ブロックを抜けた瞬間に自動でquit()が呼ばれる
headlessモードの利用と注意点
GUIを持たないheadlessモードで実行している場合、ブラウザが残っていても目に見えません。
これが原因で、気づかないうちに数十個ものブラウザプロセスがバックグラウンドで起動しているというトラブルがよくあります。
headlessモードを利用する際こそ、quit()の呼び出しを厳格に管理しなければなりません。
高度な対策:シグナルハンドリングとクリーンアップスクリプト
大規模なスクレイピングシステムや常駐プログラムでは、OSのシグナルを検知して終了させる手法も検討されます。
Ctrl+Cなどの割り込みへの対応
ユーザーがコマンドラインからスクリプトを強制終了させた場合、finallyブロックさえ実行されないことがあります。
このようなケースに対応するためには、signalモジュールを使って終了シグナルをキャッチし、その中でdriver.quit()を呼び出すように設計します。
孤立プロセスの定期的掃除
万が一プロセスが残ってしまった場合に備え、スクリプトの実行前に古いドライバプロセスを掃除するコードを入れる手法もあります。
特にWindows環境ではtaskkillコマンド、Linux環境ではpkillコマンドをPythonのsubprocess経由で実行します。
ただし、これは他の実行中のプロセスを巻き込むリスクがあるため、慎重に実装する必要があります。
import subprocess
def kill_leftover_processes():
try:
# Windowsの場合、残留しているchromedriverを強制終了
subprocess.run(["taskkill", "/f", "/im", "chromedriver.exe"], check=False)
except Exception as e:
print(f"クリーンアップ中にエラー: {e}")
# スクリプト開始時に掃除する
kill_leftover_processes()
まとめ
Python Seleniumにおけるclose()とquit()は、一見似ていますがその役割は大きく異なります。
close()は「現在の窓を閉じるだけ」であり、quit()は「すべてを閉じてプロセスを終了させる」という違いを明確に意識しましょう。
自動化スクリプトを安定させるためには、finally句やコンテキストマネージャを活用して、どのような状況下でも必ずquit()が呼ばれる構造にすることが重要です。
2026年のWeb自動化シーンにおいて、リソース管理の徹底はコードの品質を左右する大きな要素となります。
適切な終了処理をマスターして、効率的でクリーンなSelenium開発を実現してください。
