Cloud RunでSeleniumによるログインサイトのスクレイピングを実装したら503エラーに遭遇した話
はじめに
ログインが必要なWebサイトから定期的にデータを取得する必要があり、Cloud RunとSeleniumを使用してWebアプリを実装しました。開発環境では問題なく動作していたものの、本番環境でのデプロイ後に503エラーが発生。この記事では、備忘としてその原因特定から解決までの過程を共有します。
システム構成
使用技術
- Python 3.9
- Flask
- Selenium
- Cloud Run
- Docker
- gunicorn
実装の概要
- ログイン処理の自動化
- Seleniumによるフォーム入力
- ログイン後のセッション維持
- データ取得処理
- 複数ページの巡回
- テーブルデータの抽出
- CSVファイル生成
- pandasによるデータ整形
- 出力ファイルの生成
発生した問題
1. 503 Service Unavailable
本番環境(Cloud Run)でのみ発生する503エラー:
javascript
Uncaught (in promise) SyntaxError: Unexpected token 'S', "Service Unavailable" is not valid JSON
2. 問題の切り分け
ローカル環境 vs 本番環境
- ローカル:正常動作
- 本番(Cloud Run):503エラー
データ量による違い
- 30件(1ページ):正常動作
- 150件(6ページ):503エラー
3. 原因の特定
リソース使用状況を調査したところ:
メモリ消費の内訳:
- ChromeDriver: 200-300MB
- ページデータ: 50-100MB/ページ
- 取得データ: 1-2MB
合計: 約500-600MB
Cloud Runのデフォルト設定(512MB)では不足していることが判明。
解決策
1. タイムアウト設定の調整
dockerfile
Dockerfile
CMD exec gunicorn
--timeout 3600 \ # 60分
--workers 1
--threads 8
--bind :$PORT
app:app
2. Cloud Runのメモリ増設
bash
gcloud run deploy app-name
--source .
--timeout=3600
--region=asia-northeast1
--memory=1Gi
改善結果
-
パフォーマンス
- 150件のデータ取得に成功
- 6ページ分の巡回処理が安定動作
- 503エラーの解消
-
安定性
- メモリ使用量の適正化
- 処理時間の確保
学んだこと
1. Cloud Runでのスクレイピング実装時の注意点
- デフォルトメモリ(512MB)では不足するケースがある
- 適切なタイムアウト設定が重要
- ヘッドレスブラウザの動作を考慮したリソース設計
2. パフォーマンスチューニング
- メモリ使用量の事前見積もりが重要
- 段階的なテストによる問題の早期発見
- 本番環境に近い条件でのテスト実施
3. 本番環境特有の考慮点
- ローカル環境との動作の違いを意識
- リソース制限への適切な対応
- エラーハンドリングの重要性
まとめ
- Cloud RunでのSeleniumスクレイピングは要注意
- メモリとタイムアウトの適切な設定が重要
- 段階的なテストと監視が必要
スクレイピング処理をCloud Runで実装する際は、特にメモリ使用量とタイムアウト設定に注意が必要です。本記事で紹介した方法で、より安定した運用が可能になるはずです。