Python+SeleniumをVPSで動かすには?必要スペックとクラッシュ対策

Python

VPSでSeleniumを動かしているが、頻繁にクラッシュするような場合、VPSサーバーのスペックがSelenium用途だとかなり足りずにクラッシュしている可能性があります。この記事では、なぜクラッシュが起きるのか、どうすれば安定して動かせるのかを、原因分析から具体的な対策コードまでを解説します。


そもそもSeleniumはなぜ重いのか

Seleniumはブラウザを自動操作するためのツールです。PythonコードからChromeやFirefoxを実際に起動し、JavaScriptの実行・DOM操作・ネットワーク通信まで含めてフルにブラウザとして動かします。

つまり、あなたがパソコンでChromeを開いている状態をサーバー上で再現しているわけです。
当然リソースを大量に消費します。

メモリ消費の内訳

プロセス 消費メモリの目安 備考
Chrome(通常起動) 300〜800MB タブ数・ページ内容による
Chrome(headlessモード) 200〜500MB UIなしでも重い
Python本体 + Selenium 100〜200MB ライブラリ込み
OS(Ubuntuなど) 200〜400MB 常駐サービス込み
合計(概算) 800MB〜1.5GB以上 1GBでは普通に溢れる

このように1GBメモリでSeleniumを動かすのは「ギリギリ」ではなく「オーバースペックを要求している」状態です。


VPS 1GBでクラッシュする主な原因

① OOM(Out of Memory)によるプロセス強制終了

Linuxカーネルはメモリが枯渇すると、OOM Killerという機能が働き、メモリを多く使っているプロセスを強制終了します。SeleniumやChromeはメモリ消費が大きいため、真っ先に狙われます。

サーバーが突然落ちたり、Chromeが理由なく死んだりするのはたいていこれが原因です。

② /dev/shm(共有メモリ)不足

Chromeは内部で/dev/shm(共有メモリ領域)を大量に使います。VPS環境やDockerコンテナでは、この領域がデフォルトで64MB程度しかなく、Chromeが正常に動作できずにクラッシュします。

これは非常に多くのケースで見落とされがちな原因です。

③ Chromeプロセスの増殖

Seleniumを使っていると、エラーハンドリングが不十分な場合にChromeやChromedriverのプロセスが残り続けます。これが積み重なると、メモリをじわじわ食い尽くしてサーバーが不安定になります。

④ スワップ領域が未設定

多くのVPSは初期状態でSwap(仮想メモリ)が設定されていません。Swapがないと、物理メモリが限界に達した瞬間にOOM Killerが動くため、非常に不安定になります。


よくあるクラッシュ症状と読み方

エラーメッセージから原因を絞り込みましょう。

エラーメッセージ 主な原因 対策の方向性
DevToolsActivePort file doesn't exist Chrome起動失敗(メモリ・権限・shm不足) 起動オプション見直し、–no-sandbox追加
chrome not reachable Chromeプロセスが落ちている メモリ・Swap確認、プロセス掃除
session deleted because of page crash /dev/shm不足、メモリ枯渇 –disable-dev-shm-usage追加
サーバーごと落ちる OOM Killerによるプロセス強制終了 Swap追加、スペックアップ
WebDriverException: Message: unknown error ChromeとChromedriverのバージョン不一致 バージョン合わせ、selenium-manager利用

安定稼働のための対策(優先度順)

以下、効果が高い順に対策を並べます。複数組み合わせることで安定性が大幅に向上します。

  1. Chromeを軽量モードで起動する(即効性あり)
  2. –disable-dev-shm-usageを必ず設定する(見落とし多い)
  3. Swapを追加する(根本的な延命策)
  4. 残留プロセスを定期的にkillする(長期稼働向け)
  5. requestsに切り替える(可能なら最強)
  6. VPSスペックを上げる(最も確実)

Swapを使った「擬似メモリ」拡張

Swapとはディスク領域を仮想的なメモリとして使う仕組みです。速度は物理メモリより遅いですが、OOM Killerを防ぐ「保険」として非常に有効です。

Swapの設定手順(Ubuntu/Debian系)

# 2GBのSwapファイルを作成
sudo fallocate -l 2G /swapfile

# パーミッション設定
sudo chmod 600 /swapfile

# Swapとして初期化
sudo mkswap /swapfile

# Swapを有効化
sudo swapon /swapfile

# 確認
free -h

再起動後も有効にする

# /etc/fstabに追記
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Swappinessの調整(任意)

Swappinessはカーネルがどの程度積極的にSwapを使うかを示す値(0〜100)です。サーバー用途では低めに設定するのが一般的です。

# 現在の値を確認
cat /proc/sys/vm/swappiness

# 一時的に変更(推奨値:10)
sudo sysctl vm.swappiness=10

# 永続化
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

Swapを2GB追加するだけで、1GBメモリのVPSでも事実上3GBのメモリ空間を確保できます。これだけでクラッシュが劇的に減るケースが多いです。


Chromeを軽量モードで起動する設定

SeleniumでChromeを起動する際のオプション設定は非常に重要です。特に低スペック環境では以下の設定をすべて適用することを強く推奨します。

基本の軽量化設定(Python)

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()

# ヘッドレスモード(GUIなし)
options.add_argument('--headless=new')

# サンドボックス無効(root実行時必須)
options.add_argument('--no-sandbox')

# /dev/shm問題の回避(超重要)
options.add_argument('--disable-dev-shm-usage')

# GPU無効(headlessでは不要)
options.add_argument('--disable-gpu')

# 拡張機能無効
options.add_argument('--disable-extensions')

# シングルプロセスモード(メモリ削減)
options.add_argument('--single-process')

# 画像読み込み無効(高速化・メモリ削減)
options.add_argument('--blink-settings=imagesEnabled=false')

# DevTools無効
options.add_argument('--disable-dev-tools')

# ウィンドウサイズ指定(レンダリング最小化)
options.add_argument('--window-size=1280,720')

# ログ抑制
options.add_argument('--log-level=3')
options.add_experimental_option('excludeSwitches', ['enable-logging'])

driver = webdriver.Chrome(options=options)

各オプションの効果

オプション 効果 重要度
--headless=new GUI描画なし。最もメモリ削減に効く ★★★
--no-sandbox root実行時のクラッシュ防止 ★★★
--disable-dev-shm-usage /dev/shmの代わりに/tmpを使用。安定性向上 ★★★
--single-process プロセス数削減でメモリ節約 ★★☆
--disable-gpu GPU処理を無効化。headless環境では不要 ★★☆
--blink-settings=imagesEnabled=false 画像無効化。速度・メモリ両方に効果 ★★☆
--disable-extensions 拡張機能の読み込みをスキップ ★☆☆

残留プロセスの自動クリーンアップ

長時間・繰り返し実行するスクリプトでは、ChromeやChromedriverが残り続けることがあります。以下のようにtry-finallyで確実に終了させましょう。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import subprocess

def get_driver():
    options = Options()
    options.add_argument('--headless=new')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--disable-gpu')
    options.add_argument('--single-process')
    return webdriver.Chrome(options=options)

def cleanup_chrome():
    """残留ChromeプロセスをKillする"""
    subprocess.run(['pkill', '-f', 'chrome'], capture_output=True)
    subprocess.run(['pkill', '-f', 'chromedriver'], capture_output=True)

driver = None
try:
    driver = get_driver()
    driver.get('https://example.com')
    # 処理...
    print(driver.title)

except Exception as e:
    print(f"エラー: {e}")

finally:
    if driver:
        driver.quit()
    cleanup_chrome()

それでもダメなら:requests+BeautifulSoupへの切り替え

そもそもSeleniumが必要かどうかを見直すことも重要です。以下のような用途であれば、requestsライブラリとBeautifulSoupで代替できます。

requestsで代替できるケース

  • 静的なHTMLページのスクレイピング
  • APIレスポンスの取得
  • ログイン後のページ取得(セッション管理で対応可)
  • フォームのPOST送信

Seleniumが必要なケース

  • JavaScriptで動的に生成されるコンテンツの取得
  • ボタンのクリック・スクロールなどブラウザ操作が必要
  • SPA(React/Vue製)サイトのスクレイピング
  • スクリーンショットの撮影

requestsとSeleniumの比較

比較項目 requests + BeautifulSoup Selenium
メモリ使用量 10〜50MB程度 500MB〜1GB以上
処理速度 非常に速い 遅い(ブラウザ起動あり)
JS対応 ×(非対応) ◎(完全対応)
動的ページ △(ページによる)
セットアップの簡単さ △(ドライバ管理が必要)
VPS 1GBでの安定性 ◎ 問題なし × 厳しい

requestsのサンプルコード

import requests
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

response = requests.get('https://example.com', headers=headers, timeout=10)
response.raise_for_status()

soup = BeautifulSoup(response.text, 'html.parser')
title = soup.find('h1').text
print(title)

静的なページやAPIからのデータ取得が目的であれば、requestsへの切り替えがメモリを1/10以下に削減できる最も効果的な方法です。


VPS必要スペックの目安

Seleniumを使うなら、最低限どのくらいのスペックが必要か整理します。

メモリ 安定度 評価 備考
1GB 不安定 ❌ 非推奨 Swapで延命は可能。本番環境には不向き
2GB 最低ライン ⚠️ 条件付き可 軽量化オプション必須。Swapも追加推奨
4GB 安定 ✅ 推奨 並列処理・複数タブも安定して動作
8GB以上 余裕あり ✅✅ 十分 大規模スクレイピングや並列実行にも対応

CPUについて

メモリほど問題になりにくいですが、CPUが1コアの場合はChromeのレンダリングと処理が競合しやすくなります。最低でも2コアを推奨します。

ストレージ(ディスク)について

Swapファイルを2GB確保することを考えると、最低20GB以上のSSDが望ましいです。HDDはSwapのI/Oが遅く、パフォーマンスが低下します。


実務でおすすめの構成

最小構成(コスト重視)

  • VPS:2GBメモリ / 2コアCPU / 20GB SSD
  • Swap:2GB設定済み
  • Python:3.10以上
  • Chrome起動オプション:headless + 軽量化設定をフルで適用
  • 対象ページが静的なら:requestsに切り替えを検討

安定構成(安心重視)

  • VPS:4GBメモリ / 2〜4コアCPU / 40GB SSD
  • Swap:2GB設定済み(保険として)
  • Chrome起動オプション:headless + 軽量化設定
  • プロセス監視:supervisordやsystemdで自動再起動
  • ログ監視:クラッシュ検知を仕込む

自動再起動の設定例(systemd)

Seleniumスクリプトをsystemdサービスとして登録し、クラッシュ時に自動で再起動させる方法です。

# /etc/systemd/system/selenium_bot.service
[Unit]
Description=Selenium Bot
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/mybot
ExecStart=/usr/bin/python3 /home/ubuntu/mybot/main.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
# サービスの登録・起動
sudo systemctl daemon-reload
sudo systemctl enable selenium_bot
sudo systemctl start selenium_bot

# ログ確認
sudo journalctl -u selenium_bot -f

まとめ

Python+SeleniumをVPSで安定稼働させるためのポイントをまとめます。

クラッシュの原因(重要度順)

  1. メモリ不足(OOM):1GBではChromeとOSを合わせると確実に超過
  2. /dev/shm不足:VPS環境でChrome起動時のよくある落とし穴
  3. Swap未設定:保険がない状態でメモリが枯渇すると即死
  4. 残留プロセス:長期稼働時にじわじわメモリを食い尽くす

今すぐできる対策チェックリスト

  • --disable-dev-shm-usage をChromeオプションに追加した
  • --headless=new でヘッドレス起動に切り替えた
  • --no-sandbox を設定した
  • ☐ Swapを2GB以上設定した
  • ☐ try-finallyでdriver.quit()を確実に呼ぶようにした
  • ☐ 静的ページならrequestsへの切り替えを検討した
  • ☐ VPSのメモリを2GB以上に変更することを検討した

最終的な結論

状況 推奨アクション
すぐにお金をかけたくない Swap追加 + 軽量化オプションで延命
静的なページのスクレイピングが目的 requestsに切り替え(最も効果的)
本番環境として安定稼働させたい 4GB以上のVPSに移行
JavaScriptが必須のサイトを扱う 2GB VPS + 軽量化オプション + Swap

クラッシュの8割はメモリ不足が原因です。まずはSwapの追加と軽量化オプションの設定を行い、それでも改善しない場合はVPSのプランアップグレードを検討しましょう。

コメント

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