毎月の経費精算、定期的な競合価格調査、レポートのダウンロード...。「また同じ作業か」とため息をついている業務担当者は多いのではないでしょうか。
これらの繰り返し作業を自動化したいと思っても、従来の方法では「要素が見つからない」「UIが変わったら動かなくなった」といった問題で挫折することが少なくありません。
しかし、Playwright MCP + Claude Codeの組み合わせにより、この状況が根本的に変わりました。
従来の業務自動化が失敗する理由
よくある自動化の課題
業務でブラウザ自動操作を試みた際の典型的な問題:
- 要素特定の困難さ: 「このボタンのCSSセレクタがわからない」
- タイミングの問題: 「ページの読み込み完了を待てずにエラー」
- UIの微変更: 「昨日まで動いていたのに、突然動かなくなった」
- メンテナンス性: 「作った本人しか修正できない」
根本的な問題:探索と実装の混同
従来のアプローチでは、「どの要素をクリックすればいいか」を探す探索プロセスと、「実際に動作するスクリプト」を作る実装プロセスが混同されていました。
この結果、探索段階での試行錯誤が実装品質を下げ、メンテナンス性の低いスクリプトが量産されてしまいます。
二段階アプローチの威力
フェーズ1: Playwright MCPで探索的要素特定
目的: 安定して操作できる要素の特定
1. 実際のブラウザでページを開く
2. 複数のセレクタパターンを試行
3. 最も安定したセレクタを発見
4. 動作タイミングを確認
Playwright MCPの強み: - リアルタイム試行錯誤: ブラウザを見ながら要素を特定 - 複数セレクタの比較: CSS、XPath、テキストベース等を並行試験 - 動的待機の確認: 要素の表示タイミングを実測
フェーズ2: Claude CodeでPython + Seleniumの本番実装
目的: 堅牢で保守しやすい実行スクリプト
# 自動生成される堅牢なスクリプト例
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import logging
import time
class BusinessAutomation:
def __init__(self):
self.setup_logging()
self.driver = self.setup_driver()
def setup_logging(self):
logging.basicConfig(level=logging.INFO)
self.logger = logging.getLogger(__name__)
def safe_click(self, selector, timeout=10, retry=3):
"""安全なクリック処理(リトライ付き)"""
for attempt in range(retry):
try:
element = WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, selector))
)
element.click()
self.logger.info(f"Successfully clicked: {selector}")
return True
except Exception as e:
self.logger.warning(f"Click attempt {attempt + 1} failed: {e}")
time.sleep(2)
return False
Claude Codeによる実装の強み: - エラーハンドリング: 想定される全ての例外を処理 - ログ出力: 実行状況の可視化 - リトライ機構: 一時的な問題への対応 - 設定の外部化: 環境に依存しない設計
実践例1: 経費精算の自動化
業務シナリオ
毎月20件程度の経費をWebシステムに入力する作業を自動化
フェーズ1: Playwright MCPでの探索
1. 経費精算システムにログイン
2. 「新規登録」ボタンの最適セレクタを特定
3. 各入力フィールドの識別方法を確認
4. 保存処理のタイミングを測定
発見事項: - 日付フィールドはカレンダー形式のため、直接入力が困難 - 金額入力後にバリデーションで3秒の待機が必要 - 添付ファイルのアップロードは非同期処理
フェーズ2: Claude Codeでの実装
def process_expenses(self, csv_file_path):
"""CSVファイルから経費データを読み込み、自動入力"""
expenses = pd.read_csv(csv_file_path)
for index, expense in expenses.iterrows():
try:
# 新規登録画面を開く
self.safe_click("button[data-action='new-expense']")
# 日付入力(カレンダー対応)
self.input_date("input[name='expense-date']", expense['date'])
# 金額入力(バリデーション待機)
self.input_amount("input[name='amount']", expense['amount'])
# 説明入力
self.safe_input("textarea[name='description']", expense['description'])
# 添付ファイル(非同期アップロード)
if expense['receipt_path']:
self.upload_receipt(expense['receipt_path'])
# 保存処理
if self.save_expense():
self.logger.info(f"Expense {index + 1} processed successfully")
else:
self.logger.error(f"Failed to save expense {index + 1}")
except Exception as e:
self.logger.error(f"Error processing expense {index + 1}: {e}")
self.capture_screenshot(f"error_expense_{index + 1}.png")
業務効果: - 作業時間: 2時間 → 15分 - エラー率: 5% → 0% - 担当者の負担軽減
実践例2: 競合価格の定期監視
業務シナリオ
週1回、主要競合3社のサイトから価格情報を収集
フェーズ1での重要な発見
- サイトA: JavaScriptによる動的価格表示(3秒待機必要)
- サイトB: ログイン必須、セッション管理が重要
- サイトC: レート制限あり(リクエスト間隔2秒必要)
フェーズ2での実装
class CompetitorPriceMonitor:
def __init__(self):
self.results = []
self.setup_driver_with_stealth()
def monitor_all_competitors(self):
competitors = [
{'name': 'CompanyA', 'url': 'https://...', 'method': self.scrape_company_a},
{'name': 'CompanyB', 'url': 'https://...', 'method': self.scrape_company_b},
{'name': 'CompanyC', 'url': 'https://...', 'method': self.scrape_company_c},
]
for competitor in competitors:
try:
prices = competitor['method'](competitor['url'])
self.results.append({
'company': competitor['name'],
'prices': prices,
'timestamp': datetime.now()
})
except Exception as e:
self.send_alert(f"Failed to scrape {competitor['name']}: {e}")
def scrape_company_a(self, url):
"""JavaScript動的価格に対応"""
self.driver.get(url)
# 動的コンテンツの読み込み待機
WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "price-loaded"))
)
prices = []
price_elements = self.driver.find_elements(By.CSS_SELECTOR, ".product-price")
for element in price_elements:
prices.append({
'product': element.get_attribute('data-product'),
'price': element.text
})
return prices
業務効果: - 調査時間: 1時間 → 5分 - データの一貫性向上 - 価格変動の早期発見
実践例3: 月次レポートの自動ダウンロード
業務シナリオ
各種管理画面から月次データを定期取得
実装のポイント
def download_monthly_reports(self, target_month):
"""月次レポートの一括ダウンロード"""
reports = [
{'name': 'sales', 'selector': '#sales-report-btn'},
{'name': 'inventory', 'selector': '#inventory-report-btn'},
{'name': 'customer', 'selector': '#customer-report-btn'},
]
for report in reports:
try:
# 日付範囲設定
self.set_date_range(target_month)
# レポート生成
self.safe_click(report['selector'])
# 生成完了待機(進行状況バー監視)
self.wait_for_report_generation()
# ダウンロード実行
download_path = self.download_report(report['name'], target_month)
# ファイル整理
self.organize_downloaded_file(download_path, report['name'])
except Exception as e:
self.logger.error(f"Failed to download {report['name']}: {e}")
導入時の重要ポイント
セキュリティ考慮事項
認証情報の管理:
import os
from cryptography.fernet import Fernet
class SecureCredentials:
def __init__(self):
self.cipher = Fernet(os.environ['AUTOMATION_KEY'])
def get_credentials(self, service_name):
encrypted_data = os.environ[f'{service_name}_CREDENTIALS']
return self.cipher.decrypt(encrypted_data.encode()).decode()
アクセス制御: - 自動化専用アカウントの利用 - 最小権限の原則 - 実行ログの保管
エラー監視とアラート
def send_alert(self, message, severity='WARNING'):
"""業務チームへのアラート通知"""
if severity == 'CRITICAL':
# Slack/Teams通知
self.send_slack_notification(message)
# メール通知
self.send_email_alert(message)
else:
# ログ記録のみ
self.logger.warning(message)
メンテナンス性の確保
設定の外部化:
# automation_config.yaml
selectors:
login_button: "button[data-testid='login']"
amount_field: "input[name='amount']"
save_button: ".save-action"
timeouts:
page_load: 10
element_wait: 5
download_wait: 30
retry_counts:
click_retry: 3
input_retry: 2
ドキュメント化: - 各処理の業務的意味 - 設定パラメータの説明 - トラブルシューティング手順
まとめ
Playwright MCP + Claude Codeの二段階アプローチにより、業務自動化は新しいレベルに到達しました。
従来の課題: - 要素特定の困難さ - 不安定な動作 - メンテナンス性の低さ
新アプローチの効果: - 探索と実装の分離による高品質化 - エラーハンドリングとリトライによる堅牢性 - 設定外部化とドキュメント化による保守性
重要なのは、技術的な実装だけでなく、業務プロセス全体を見直す視点です。自動化により生まれた時間を、より価値の高い業務に投入することで、真の業務効率化が実現できるのです。
安定したブラウザ自動操作による業務革新は、もはや一部の技術者だけのものではありません。適切なツールと手法により、すべての業務担当者が恩恵を受けられる時代が到来しています。