{ "cells": [ { "cell_type": "markdown", "id": "a01c3e5d", "metadata": {}, "source": [ "# 🖼️ RPA自動キャプチャテストシステム\n", "\n", "アプリ再起動時に自動で画面をキャプチャして指定場所に保存するシステム\n", "\n", "## 📋 機能概要\n", "- ✅ 自動スクリーンショット取得\n", "- ✅ 指定フォルダへの自動保存\n", "- ✅ タイムスタンプ付きファイル名\n", "- ✅ エラーハンドリング\n", "- ✅ 履歴管理" ] }, { "cell_type": "code", "execution_count": 1, "id": "1d55d6ed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "📚 ライブラリ読み込み完了\n", "⏰ 実行開始時刻: 2025-06-12 02:23:33\n" ] } ], "source": [ "# 必要ライブラリのインストール・インポート\n", "import sys\n", "import os\n", "import asyncio\n", "from datetime import datetime\n", "from pathlib import Path\n", "import time\n", "import json\n", "\n", "# プロジェクトルートをパスに追加\n", "sys.path.append('/workspaces/fastapi_django_main_live')\n", "\n", "print(\"📚 ライブラリ読み込み完了\")\n", "print(f\"⏰ 実行開始時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "8fb1a634", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "✅ RPA データベース初期化完了\n", "✅ RPA機能利用可能\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "IMPORTANT: You are using gradio version 4.31.5, however version 4.44.1 is available, please upgrade.\n", "--------\n" ] } ], "source": [ "# RPAモジュールの読み込み\n", "try:\n", " from contbk.gra_12_rpa.rpa_automation import RPAManager\n", " RPA_AVAILABLE = True\n", " print(\"✅ RPA機能利用可能\")\n", "except ImportError as e:\n", " RPA_AVAILABLE = False\n", " print(f\"❌ RPA機能利用不可: {e}\")\n", " print(\"📦 Playwrightのインストールが必要な場合があります\")" ] }, { "cell_type": "code", "execution_count": 3, "id": "fe9aefbe", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "💾 保存先: /workspaces/fastapi_django_main_live/docs/images/auto_captures\n", "🌐 対象URL数: 3\n", "🎯 セレクター数: 3\n", "⚙️ キャプチャ設定完了\n" ] } ], "source": [ "# キャプチャ設定\n", "class CaptureConfig:\n", " \"\"\"キャプチャ設定クラス\"\"\"\n", " \n", " def __init__(self):\n", " # 保存先ディレクトリ\n", " self.save_dir = Path(\"/workspaces/fastapi_django_main_live/docs/images/auto_captures\")\n", " self.save_dir.mkdir(parents=True, exist_ok=True)\n", " \n", " # キャプチャ対象URL(Codespace URL)\n", " self.target_urls = [\n", " \"https://ideal-halibut-4q5qp79g2jp9-7860.app.github.dev/\",\n", " \"https://ideal-halibut-4q5qp79g2jp9-7860.app.github.dev/?tab=0\", # 最初のタブ\n", " \"https://ideal-halibut-4q5qp79g2jp9-7860.app.github.dev/?tab=1\", # 2番目のタブ\n", " ]\n", " \n", " # セレクター指定キャプチャ\n", " self.selector_captures = {\n", " \"main_interface\": \".gradio-container\",\n", " \"tabs_area\": \".tab-nav\",\n", " \"rpa_debug_tab\": \"button[data-testid='🔍 RPA + AI デバッグ-tab-button']\"\n", " }\n", " \n", " # 待機時間設定\n", " self.wait_time = 5 # 画面読み込み待機秒数\n", " self.capture_interval = 2 # キャプチャ間隔秒数\n", " \n", " # ファイル名形式\n", " self.filename_format = \"capture_{timestamp}_{type}.png\"\n", " \n", " # 履歴保存ファイル\n", " self.history_file = self.save_dir / \"capture_history.json\"\n", " \n", " print(f\"💾 保存先: {self.save_dir}\")\n", " print(f\"🌐 対象URL数: {len(self.target_urls)}\")\n", " print(f\"🎯 セレクター数: {len(self.selector_captures)}\")\n", "\n", "# 設定インスタンス作成\n", "config = CaptureConfig()\n", "print(\"⚙️ キャプチャ設定完了\")" ] }, { "cell_type": "code", "execution_count": 4, "id": "42ca229a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ RPA データベース初期化完了\n", "🔧 自動キャプチャシステム初期化完了\n" ] } ], "source": [ "# キャプチャ実行クラス\n", "class AutoCaptureSystem:\n", " \"\"\"自動キャプチャシステム\"\"\"\n", " \n", " def __init__(self, config):\n", " self.config = config\n", " self.rpa_manager = RPAManager() if RPA_AVAILABLE else None\n", " self.capture_results = []\n", " \n", " async def capture_single_url(self, target_info):\n", " \"\"\"単一URLのキャプチャ\"\"\"\n", " name = target_info[\"name\"]\n", " url = target_info[\"url\"]\n", " prefix = target_info[\"filename_prefix\"]\n", " wait_time = target_info[\"wait_time\"]\n", " \n", " print(f\"\\n📸 キャプチャ開始: {name}\")\n", " print(f\"🌐 URL: {url}\")\n", " \n", " try:\n", " if not self.rpa_manager:\n", " return {\n", " \"name\": name,\n", " \"success\": False,\n", " \"error\": \"RPA機能が利用できません\"\n", " }\n", " \n", " # スクリーンショット取得\n", " img, message = await self.rpa_manager.capture_screenshot(\n", " url=url,\n", " selector=None,\n", " wait_time=wait_time\n", " )\n", " \n", " if img:\n", " # ファイル名生成\n", " timestamp = datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n", " filename = f\"{prefix}_{timestamp}.png\"\n", " filepath = self.config.save_dir / filename\n", " \n", " # 画像保存\n", " img.save(filepath)\n", " \n", " result = {\n", " \"name\": name,\n", " \"success\": True,\n", " \"filepath\": str(filepath),\n", " \"filename\": filename,\n", " \"timestamp\": datetime.now().isoformat(),\n", " \"url\": url,\n", " \"message\": message\n", " }\n", " \n", " print(f\"✅ 保存完了: {filename}\")\n", " return result\n", " else:\n", " print(f\"❌ キャプチャ失敗: {message}\")\n", " return {\n", " \"name\": name,\n", " \"success\": False,\n", " \"error\": message\n", " }\n", " \n", " except Exception as e:\n", " error_msg = f\"エラー: {str(e)}\"\n", " print(f\"❌ {error_msg}\")\n", " return {\n", " \"name\": name,\n", " \"success\": False,\n", " \"error\": error_msg\n", " }\n", " \n", " async def capture_all_urls(self):\n", " \"\"\"全URLのキャプチャ実行\"\"\"\n", " print(\"🚀 一括キャプチャ開始\")\n", " print(\"=\" * 50)\n", " \n", " results = []\n", " \n", " for target_info in self.config.target_urls:\n", " result = await self.capture_single_url(target_info)\n", " results.append(result)\n", " \n", " # 次のキャプチャまで少し待機\n", " await asyncio.sleep(2)\n", " \n", " self.capture_results = results\n", " return results\n", " \n", " def save_history(self, results):\n", " \"\"\"履歴をJSONファイルに保存\"\"\"\n", " try:\n", " # 既存履歴を読み込み\n", " if self.config.history_file.exists():\n", " with open(self.config.history_file, 'r', encoding='utf-8') as f:\n", " history = json.load(f)\n", " else:\n", " history = []\n", " \n", " # 新しい実行記録を追加\n", " session_record = {\n", " \"session_timestamp\": datetime.now().isoformat(),\n", " \"total_captures\": len(results),\n", " \"successful_captures\": len([r for r in results if r[\"success\"]]),\n", " \"results\": results\n", " }\n", " \n", " history.append(session_record)\n", " \n", " # 履歴は最新10セッションまで保持\n", " history = history[-10:]\n", " \n", " # ファイルに保存\n", " with open(self.config.history_file, 'w', encoding='utf-8') as f:\n", " json.dump(history, f, ensure_ascii=False, indent=2)\n", " \n", " print(f\"📝 履歴保存完了: {self.config.history_file}\")\n", " \n", " except Exception as e:\n", " print(f\"⚠️ 履歴保存エラー: {e}\")\n", " \n", " def show_results(self, results):\n", " \"\"\"結果サマリーを表示\"\"\"\n", " print(\"\\n📊 キャプチャ結果サマリー\")\n", " print(\"=\" * 50)\n", " \n", " successful = [r for r in results if r[\"success\"]]\n", " failed = [r for r in results if not r[\"success\"]]\n", " \n", " print(f\"✅ 成功: {len(successful)}件\")\n", " print(f\"❌ 失敗: {len(failed)}件\")\n", " print(f\"📁 保存先: {self.config.save_dir}\")\n", " \n", " if successful:\n", " print(\"\\n🎯 成功したキャプチャ:\")\n", " for result in successful:\n", " print(f\" ✅ {result['name']}: {result['filename']}\")\n", " \n", " if failed:\n", " print(\"\\n❌ 失敗したキャプチャ:\")\n", " for result in failed:\n", " print(f\" ❌ {result['name']}: {result['error']}\")\n", "\n", "# システム初期化\n", "capture_system = AutoCaptureSystem(config)\n", "print(\"🔧 自動キャプチャシステム初期化完了\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "f8f49782", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ サーバー起動中 - キャプチャ実行可能\n" ] } ], "source": [ "# サーバー起動確認\n", "import requests\n", "\n", "def check_server_status():\n", " \"\"\"サーバーの起動状況を確認\"\"\"\n", " try:\n", " response = requests.get(\"http://localhost:7860\", timeout=5)\n", " if response.status_code == 200:\n", " print(\"✅ サーバー起動中 - キャプチャ実行可能\")\n", " return True\n", " else:\n", " print(f\"⚠️ サーバー応答異常: {response.status_code}\")\n", " return False\n", " except requests.exceptions.RequestException as e:\n", " print(f\"❌ サーバー未起動または接続エラー: {e}\")\n", " print(\"💡 app.py を実行してからキャプチャを開始してください\")\n", " return False\n", "\n", "server_ready = check_server_status()" ] }, { "cell_type": "code", "execution_count": null, "id": "257ed26a", "metadata": {}, "outputs": [], "source": [ "# 🚀 メインキャプチャ実行\n", "if server_ready and RPA_AVAILABLE:\n", " print(\"🎬 自動キャプチャを開始します...\")\n", " \n", " # 非同期でキャプチャ実行\n", " results = await capture_system.capture_all_urls()\n", " \n", " # 結果表示\n", " capture_system.show_results(results)\n", " \n", " # 履歴保存\n", " capture_system.save_history(results)\n", " \n", " print(\"\\n🎉 自動キャプチャ完了!\")\n", " \n", "else:\n", " print(\"⚠️ キャプチャ実行条件が満たされていません\")\n", " if not server_ready:\n", " print(\" - サーバーが起動していません\")\n", " if not RPA_AVAILABLE:\n", " print(\" - RPA機能が利用できません\")" ] }, { "cell_type": "code", "execution_count": null, "id": "3b942c29", "metadata": {}, "outputs": [], "source": [ "# キャプチャ履歴の表示\n", "def show_capture_history():\n", " \"\"\"キャプチャ履歴を表示\"\"\"\n", " try:\n", " if config.history_file.exists():\n", " with open(config.history_file, 'r', encoding='utf-8') as f:\n", " history = json.load(f)\n", " \n", " print(\"📚 キャプチャ履歴\")\n", " print(\"=\" * 50)\n", " \n", " for i, session in enumerate(reversed(history[-5:]), 1):\n", " timestamp = session[\"session_timestamp\"][:19].replace(\"T\", \" \")\n", " total = session[\"total_captures\"]\n", " success = session[\"successful_captures\"]\n", " \n", " print(f\"#{i} {timestamp} - {success}/{total} 成功\")\n", " \n", " for result in session[\"results\"]:\n", " status = \"✅\" if result[\"success\"] else \"❌\"\n", " name = result[\"name\"]\n", " if result[\"success\"]:\n", " filename = result[\"filename\"]\n", " print(f\" {status} {name}: {filename}\")\n", " else:\n", " error = result[\"error\"][:50]\n", " print(f\" {status} {name}: {error}\")\n", " print()\n", " else:\n", " print(\"📭 履歴ファイルが見つかりません\")\n", " \n", " except Exception as e:\n", " print(f\"❌ 履歴表示エラー: {e}\")\n", "\n", "show_capture_history()" ] }, { "cell_type": "code", "execution_count": null, "id": "cc570d0a", "metadata": {}, "outputs": [], "source": [ "# 保存されたファイル一覧表示\n", "def show_saved_files():\n", " \"\"\"保存されたキャプチャファイル一覧を表示\"\"\"\n", " try:\n", " files = list(config.save_dir.glob(\"*.png\"))\n", " files.sort(key=lambda f: f.stat().st_mtime, reverse=True)\n", " \n", " print(f\"📁 保存ファイル一覧 ({len(files)}件)\")\n", " print(\"=\" * 50)\n", " \n", " for i, file in enumerate(files[:10], 1):\n", " stat = file.stat()\n", " size_mb = stat.st_size / (1024 * 1024)\n", " mtime = datetime.fromtimestamp(stat.st_mtime).strftime(\"%Y-%m-%d %H:%M:%S\")\n", " \n", " print(f\"{i:2d}. {file.name}\")\n", " print(f\" 📅 {mtime} | 📏 {size_mb:.2f}MB\")\n", " \n", " if len(files) > 10:\n", " print(f\" ...他 {len(files) - 10} ファイル\")\n", " \n", " except Exception as e:\n", " print(f\"❌ ファイル一覧取得エラー: {e}\")\n", "\n", "show_saved_files()" ] }, { "cell_type": "code", "execution_count": null, "id": "d9ffa84a", "metadata": {}, "outputs": [], "source": [ "# 手動キャプチャ実行(テスト用)\n", "async def manual_capture_test(url, name):\n", " \"\"\"手動でキャプチャをテスト実行\"\"\"\n", " print(f\"🧪 手動キャプチャテスト: {name}\")\n", " \n", " target_info = {\n", " \"name\": name,\n", " \"url\": url,\n", " \"filename_prefix\": \"manual_test\",\n", " \"wait_time\": 3\n", " }\n", " \n", " result = await capture_system.capture_single_url(target_info)\n", " \n", " if result[\"success\"]:\n", " print(f\"✅ テストキャプチャ成功: {result['filename']}\")\n", " else:\n", " print(f\"❌ テストキャプチャ失敗: {result['error']}\")\n", " \n", " return result\n", "\n", "# 使用例(必要に応じてコメントアウトを外す)\n", "# if server_ready and RPA_AVAILABLE:\n", "# test_result = await manual_capture_test(\"http://localhost:7860\", \"手動テスト\")" ] }, { "cell_type": "markdown", "id": "cefee865", "metadata": {}, "source": [ "## 🎯 使用方法\n", "\n", "### 🚀 基本的な使い方\n", "1. **アプリケーション起動**: `python app.py` でメインアプリを起動\n", "2. **ノートブック実行**: 上から順番にセルを実行\n", "3. **自動キャプチャ**: メインキャプチャセルで一括実行\n", "4. **結果確認**: 履歴とファイル一覧で確認\n", "\n", "### 📁 ファイル保存先\n", "- **キャプチャ画像**: `/docs/images/auto_captures/`\n", "- **履歴ファイル**: `/docs/images/auto_captures/capture_history.json`\n", "\n", "### 🔧 カスタマイズ\n", "- **対象URL追加**: `CaptureConfig` クラスの `target_urls` に追加\n", "- **保存先変更**: `save_dir` を変更\n", "- **待機時間調整**: `wait_time` で調整\n", "\n", "### 💡 トラブルシューティング\n", "- **サーバー未起動**: `python app.py` でアプリを起動\n", "- **RPA機能エラー**: Playwright のインストール確認\n", "- **権限エラー**: 保存先ディレクトリの権限確認" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.12" } }, "nbformat": 4, "nbformat_minor": 5 }