ブログに戻る

APIを通じてプロキシ使用統計を取得する方法:トラフィック管理の自動化

APIプロキシプロバイダーを使用して統計データを取得するための詳細なガイド:コード例、自動化手法、ビジネスプロセスへの統合。

📅2026年2月16日
```html

多くのプロキシを扱う場合—アービトラージ、スクレイピング、またはマルチアカウントのために—手動でのトラフィック管理は悪夢に変わります。プロキシプロバイダーのAPIを使用すると、トラフィックの残高、アクティブセッション、IPアドレスごとの消費、使用履歴を自動的に取得できます。このガイドでは、Python、Node.js、cURLのコード例を通じて、統計管理のためのAPIの統合方法を説明します。

プロキシ統計の自動化が必要な理由

10〜50のプロキシを異なるプロジェクトで管理している場合、プロバイダーの個人アカウントを通じて残高とトラフィックの消費を手動で確認することは非効率的になります。APIは、いくつかの重要な課題を解決します:

API統計の主なタスク:

  • トラフィック残高の監視 — リミットに達した際の自動通知
  • プロジェクトごとの消費管理 — クライアントやタスク間のコスト配分
  • 効果分析 — どのプロキシがより多くのトラフィックを消費しているか、その理由
  • ダウンタイムの防止 — トラフィックが終了する前に残高を補充
  • CRM/請求システムへの統合 — ビジネスプロセスにおけるプロキシのコストを自動的に管理

多数のアカウントを通じて広告を運用するアービトラージャーにとって、どのプロキシがアクティブで、どれだけのトラフィックが残っているかを把握することは極めて重要です—リミットが切れて突然ブロックされることは、数千ドルの利益を失う可能性があります。InstagramやTikTokのクライアントアカウントを管理するSMMエージェンシーにとって、自動化はプロキシの使用に対して正確な請求を行うことを可能にします。

マーケットプレイスのスクレイパー(Wildberries、Ozon、Avito)は、主要なプロキシのリミットが切れた際に自動的にバックアッププロキシに切り替えることができます。APIは、手動介入なしで24時間365日稼働する冗長システムを構築する機会を提供します。

プロキシプロバイダーのAPIの基本

現代のほとんどのプロキシプロバイダーは、サービスを管理するためのRESTful APIを提供しています。APIは標準的なスキームに従って動作します: 認証パラメータを含むHTTPリクエストを特定のエンドポイントに送信し、サーバーはデータを含むJSONを返します。

APIコンポーネント 説明
基本URL プロバイダーのAPIの基本アドレス https://api.provider.com/v1
認証 APIキーまたはBearerトークン Authorization: Bearer YOUR_API_KEY
エンドポイント さまざまな操作のための具体的なパス /statistics, /balance
レスポンス形式 データ構造 status、data、errorフィールドを含むJSON
レート制限 1分あたりのリクエスト制限 60〜300リクエスト/分

プロキシプロバイダーからの典型的なJSONレスポンスの構造は次のようになります:

{
  "status": "success",
  "data": {
    "balance": 1250.50,
    "traffic_used_gb": 45.2,
    "traffic_remaining_gb": 54.8,
    "active_proxies": 15,
    "last_updated": "2024-01-15T10:30:00Z"
  },
  "error": null
}

APIを使用する際は、レート制限(リクエスト数の制限)を考慮することが重要です。ほとんどのプロバイダーは1分あたり60〜300リクエストを許可しています。統計を監視するには十分です—通常、リクエストは5〜15分ごとに行われます。

認証とAPIキーの取得

APIを使用する最初のステップは、認証キーを取得することです。プロバイダーによってプロセスは異なりますが、一般的な流れは同じです:

APIキー取得のステップバイステップガイド:

  1. プロキシプロバイダーの個人アカウントにログイン
  2. "API"または"設定" → "APIアクセス"セクションを見つける
  3. "APIキーを作成"または"トークンを生成"ボタンをクリック
  4. キーをコピーして安全な場所に保存(1回だけ表示されます)
  5. プロバイダーがIPアドレスへのバインディングを要求する場合は、IPホワイトリストを設定
  6. cURLまたはPostmanを通じてテストリクエストでキーを確認

プロキシプロバイダーのAPIには、主に2つの認証方法があります:

方法 動作方法 ヘッダーの例
Bearerトークン トークンはAuthorizationヘッダーに渡されます Authorization: Bearer abc123...
APIキーをパラメータとして キーはGET/POSTパラメータとして渡されます ?api_key=abc123...

重要: Gitリポジトリに含まれるコードにAPIキーを保存しないでください。環境変数(.envファイル)やシークレットマネージャー(AWS Secrets Manager、HashiCorp Vault)を使用してください。キーが漏洩した場合は、すぐに個人アカウントでキーを無効にし、新しいキーを生成してください。

統計取得のための主要エンドポイント

各プロバイダーには独自のAPI構造がありますが、ほとんどは統計取得のための標準的なエンドポイントセットを提供しています。一般的なメソッドを見てみましょう:

エンドポイント メソッド 返される内容
/balance GET 現在の残高とトラフィックの残高
/statistics GET 期間中の使用統計の概要
/statistics/proxy/{id} GET 特定のプロキシに関する統計
/sessions/active GET アクティブなプロキシセッションのリスト
/traffic/history GET 日ごとのトラフィック消費の履歴
/proxies/list GET すべてのプロキシのリストとそのステータス

リクエストのパラメータには通常、時間範囲やフィルターが含まれます:

GET /statistics?from=2024-01-01&to=2024-01-15&proxy_type=residential
GET /traffic/history?period=7d&group_by=day
GET /sessions/active?status=online&country=US

レジデンシャルプロキシを使用する場合、セッションの統計を取得するエンドポイントが特に重要です。なぜなら、これらはIPのローテーションを頻繁に使用するからです。APIを使用すると、期間中に使用されたユニークなIPの数や、各セッションを通過したトラフィックの量を追跡できます。

統計取得のためのPythonコード例

Pythonは、requestsライブラリのおかげで、プロキシの自動化作業に最も人気のある言語です。APIを通じて統計を取得するための実用的な例を見てみましょう。

残高とトラフィックの基本リクエスト

import requests
import os
from datetime import datetime

# 環境変数からのAPI認証情報
API_KEY = os.getenv('PROXY_API_KEY')
BASE_URL = 'https://api.proxyprovider.com/v1'

def get_balance_statistics():
    """残高と全体の統計を取得"""
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.get(
            f'{BASE_URL}/balance',
            headers=headers,
            timeout=10
        )
        response.raise_for_status()
        
        data = response.json()
        
        print(f"=== {datetime.now().strftime('%Y-%m-%d %H:%M')}のプロキシ統計 ===")
        print(f"残高: ${data['balance']:.2f}")
        print(f"使用されたトラフィック: {data['traffic_used_gb']:.2f} GB")
        print(f"残りのトラフィック: {data['traffic_remaining_gb']:.2f} GB")
        print(f"アクティブなプロキシ: {data['active_proxies']}")
        
        return data
        
    except requests.exceptions.RequestException as e:
        print(f"リクエスト中のエラー: {e}")
        return None

# 関数の呼び出し
stats = get_balance_statistics()

期間中の詳細な統計取得

from datetime import datetime, timedelta
import requests

def get_traffic_history(days=7):
    """N日間のトラフィック消費の履歴を取得"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # 時間範囲の計算
    end_date = datetime.now()
    start_date = end_date - timedelta(days=days)
    
    params = {
        'from': start_date.strftime('%Y-%m-%d'),
        'to': end_date.strftime('%Y-%m-%d'),
        'group_by': 'day'
    }
    
    response = requests.get(
        f'{BASE_URL}/traffic/history',
        headers=headers,
        params=params,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== 過去{days}日間のトラフィック消費 ===")
        for day in data['daily_stats']:
            print(f"{day['date']}: {day['traffic_gb']:.2f} GB "
                  f"({day['requests']}リクエスト)")
        
        total = sum(day['traffic_gb'] for day in data['daily_stats'])
        print(f"\n期間中の合計: {total:.2f} GB")
        
        return data
    else:
        print(f"エラー {response.status_code}: {response.text}")
        return None

# 1週間の統計を取得
history = get_traffic_history(7)

特定のプロキシの統計監視

def get_proxy_statistics(proxy_id):
    """特定のプロキシの統計を取得"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    response = requests.get(
        f'{BASE_URL}/statistics/proxy/{proxy_id}',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        data = response.json()
        
        print(f"\n=== プロキシ {proxy_id} の統計 ===")
        print(f"IPアドレス: {data['ip_address']}")
        print(f"国: {data['country']}")
        print(f"タイプ: {data['proxy_type']}")
        print(f"ステータス: {data['status']}")
        print(f"使用されたトラフィック: {data['traffic_used_mb']:.2f} MB")
        print(f"リクエストの総数: {data['total_requests']}")
        print(f"最終活動: {data['last_activity']}")
        
        return data
    else:
        print(f"プロキシ {proxy_id} が見つかりません")
        return None

def get_all_proxies_stats():
    """すべてのプロキシの統計を取得"""
    headers = {'Authorization': f'Bearer {API_KEY}'}
    
    # まず、すべてのプロキシのリストを取得
    response = requests.get(
        f'{BASE_URL}/proxies/list',
        headers=headers,
        timeout=10
    )
    
    if response.status_code == 200:
        proxies = response.json()['proxies']
        
        print(f"\n=== {len(proxies)} プロキシの統計 ===\n")
        
        total_traffic = 0
        for proxy in proxies:
            stats = get_proxy_statistics(proxy['id'])
            if stats:
                total_traffic += stats['traffic_used_mb']
        
        print(f"\n=== 合計トラフィック消費: {total_traffic/1024:.2f} GB ===")
        
        return proxies
    else:
        print("プロキシのリスト取得中にエラーが発生しました")
        return None

# すべてのプロキシの統計を取得
all_stats = get_all_proxies_stats()

これらの例は、APIとの基本的な操作を示しています。プロダクションシステムでは、エラーハンドリング、ネットワーク障害時のリトライロジック、結果のキャッシュを追加して、プロバイダーのレート制限を超えないようにしてください。

トラフィック監視のためのNode.jsコード例

Node.jsは、バックグラウンドで動作し、重要なイベントが発生した際に通知を送信する監視マイクロサービスの作成に最適です。HTTPリクエストのためにaxiosライブラリを使用します。

APIプロキシ用の基本クラス

const axios = require('axios');
require('dotenv').config();

class ProxyAPIClient {
  constructor() {
    this.baseURL = 'https://api.proxyprovider.com/v1';
    this.apiKey = process.env.PROXY_API_KEY;
    
    this.client = axios.create({
      baseURL: this.baseURL,
      timeout: 10000,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getBalance() {
    try {
      const response = await this.client.get('/balance');
      return response.data;
    } catch (error) {
      console.error('残高取得中のエラー:', error.message);
      throw error;
    }
  }

  async getStatistics(params = {}) {
    try {
      const response = await this.client.get('/statistics', { params });
      return response.data;
    } catch (error) {
      console.error('統計取得中のエラー:', error.message);
      throw error;
    }
  }

  async getTrafficHistory(days = 7) {
    const endDate = new Date();
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - days);

    const params = {
      from: startDate.toISOString().split('T')[0],
      to: endDate.toISOString().split('T')[0],
      group_by: 'day'
    };

    try {
      const response = await this.client.get('/traffic/history', { params });
      return response.data;
    } catch (error) {
      console.error('トラフィック履歴取得中のエラー:', error.message);
      throw error;
    }
  }

  async getProxyStats(proxyId) {
    try {
      const response = await this.client.get(`/statistics/proxy/${proxyId}`);
      return response.data;
    } catch (error) {
      console.error(`プロキシ ${proxyId} の統計取得中のエラー:`, error.message);
      throw error;
    }
  }
}

module.exports = ProxyAPIClient;

通知付き自動監視

const ProxyAPIClient = require('./ProxyAPIClient');
const nodemailer = require('nodemailer');

class ProxyMonitor {
  constructor(checkIntervalMinutes = 15) {
    this.api = new ProxyAPIClient();
    this.checkInterval = checkIntervalMinutes * 60 * 1000;
    this.thresholds = {
      trafficWarning: 10, // GB - 警告
      trafficCritical: 5,  // GB - クリティカルレベル
      balanceWarning: 50   // USD - 残高警告
    };
  }

  async checkAndNotify() {
    try {
      const balance = await this.api.getBalance();
      
      console.log(`[${new Date().toISOString()}] 統計をチェック中...`);
      console.log(`残高: $${balance.balance.toFixed(2)}`);
      console.log(`残りのトラフィック: ${balance.traffic_remaining_gb.toFixed(2)} GB`);

      // クリティカル閾値のチェック
      const alerts = [];

      if (balance.traffic_remaining_gb <= this.thresholds.trafficCritical) {
        alerts.push({
          level: 'critical',
          message: `クリティカルなトラフィック不足: 残り ${balance.traffic_remaining_gb.toFixed(2)} GB!`
        });
      } else if (balance.traffic_remaining_gb <= this.thresholds.trafficWarning) {
        alerts.push({
          level: 'warning',
          message: `トラフィック不足: 残り ${balance.traffic_remaining_gb.toFixed(2)} GB`
        });
      }

      if (balance.balance <= this.thresholds.balanceWarning) {
        alerts.push({
          level: 'warning',
          message: `残高が低い: $${balance.balance.toFixed(2)}`
        });
      }

      // 通知の送信
      if (alerts.length > 0) {
        await this.sendAlerts(alerts, balance);
      }

      return { balance, alerts };
    } catch (error) {
      console.error('監視中のエラー:', error);
      await this.sendErrorNotification(error);
    }
  }

  async sendAlerts(alerts, balance) {
    console.log('\n⚠️  注意! 問題が発生しました:');
    alerts.forEach(alert => {
      console.log(`[${alert.level.toUpperCase()}] ${alert.message}`);
    });

    // メール送信(SMTPを設定)
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
      }
    });

    const emailBody = `
      プロキシに問題が発生しました:
      
      ${alerts.map(a => `- ${a.message}`).join('\n')}
      
      現在の統計:
      - 残高: $${balance.balance.toFixed(2)}
      - 残りのトラフィック: ${balance.traffic_remaining_gb.toFixed(2)} GB
      - 使用された: ${balance.traffic_used_gb.toFixed(2)} GB
      - アクティブなプロキシ: ${balance.active_proxies}
      
      残高を補充するか、負荷を減らすことをお勧めします。
    `;

    await transporter.sendMail({
      from: process.env.ALERT_FROM_EMAIL,
      to: process.env.ALERT_TO_EMAIL,
      subject: '⚠️ プロキシ警告',
      text: emailBody
    });
  }

  start() {
    console.log(`プロキシ監視を開始します(${this.checkInterval / 60000}分ごとにチェック)`);
    
    // 最初のチェックをすぐに実行
    this.checkAndNotify();
    
    // 定期的なチェック
    setInterval(() => {
      this.checkAndNotify();
    }, this.checkInterval);
  }
}

// 監視の開始
const monitor = new ProxyMonitor(15); // 15分ごとにチェック
monitor.start();

このコードは、15分ごとに統計をチェックし、クリティカルな閾値に達した際にメール通知を送信するバックグラウンドサービスを作成します。モバイルプロキシは通常レジデンシャルプロキシよりも高価であるため、この監視は支出管理に特に重要です。

cURLによるリクエストの例

cURLは、コマンドラインからAPIをテストするための汎用ツールです。エンドポイントの迅速なチェックや統合のデバッグに便利です。

残高の取得

# 残高の基本リクエスト
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# 美しいJSONフォーマット(jqを使用)
curl -X GET "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

# 特定のフィールドを抽出
curl -s "https://api.proxyprovider.com/v1/balance" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.traffic_remaining_gb'

期間中の統計取得

# 過去7日間の統計
curl -X GET "https://api.proxyprovider.com/v1/traffic/history?from=2024-01-08&to=2024-01-15&group_by=day" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.daily_stats'

# 特定のタイプのプロキシに関する統計
curl -X GET "https://api.proxyprovider.com/v1/statistics?proxy_type=residential&country=US" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.'

アクティブなプロキシのリスト取得

# すべてのアクティブなプロキシのリスト
curl -X GET "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies[] | {id, ip_address, country, proxy_type}'

# アクティブなプロキシの数をカウント
curl -s "https://api.proxyprovider.com/v1/proxies/list?status=active" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  | jq '.proxies | length'

自動チェック用のBashスクリプト

#!/bin/bash

# 設定
API_KEY="YOUR_API_KEY"
BASE_URL="https://api.proxyprovider.com/v1"
TRAFFIC_THRESHOLD=10  # GB - 警告閾値

# 統計の取得
response=$(curl -s "${BASE_URL}/balance" \
  -H "Authorization: Bearer ${API_KEY}")

# JSONのパース
traffic_remaining=$(echo "$response" | jq -r '.traffic_remaining_gb')
balance=$(echo "$response" | jq -r '.balance')
active_proxies=$(echo "$response" | jq -r '.active_proxies')

# 統計の出力
echo "=== プロキシ統計 $(date '+%Y-%m-%d %H:%M:%S') ==="
echo "残りのトラフィック: ${traffic_remaining} GB"
echo "残高: \$${balance}"
echo "アクティブなプロキシ: ${active_proxies}"

# 閾値のチェック
if (( $(echo "$traffic_remaining < $TRAFFIC_THRESHOLD" | bc -l) )); then
  echo "⚠️  注意: トラフィックが少ない! 残り ${traffic_remaining} GB"
  
  # 通知の送信(例えば、Telegramを通じて)
  # curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  #   -d chat_id="${TELEGRAM_CHAT_ID}" \
  #   -d text="⚠️ プロキシのトラフィックが少ない: ${traffic_remaining} GB"
fi

このスクリプトをcheck_proxy_stats.shとして保存し、実行権限を与え(chmod +x check_proxy_stats.sh)、cronに追加して毎時自動実行します:

0 * * * * /path/to/check_proxy_stats.sh >> /var/log/proxy_monitor.log 2>&1

監視と通知の自動化

手動での統計確認は非効率的です—スマートな通知を伴う自動化が必要です。統合を伴う完全な監視システムを考えてみましょう。

Telegramとの統合による通知

import requests
import os
from datetime import datetime

class TelegramNotifier:
    def __init__(self):
        self.bot_token = os.getenv('TELEGRAM_BOT_TOKEN')
        self.chat_id = os.getenv('TELEGRAM_CHAT_ID')
        self.base_url = f'https://api.telegram.org/bot{self.bot_token}'
    
    def send_message(self, text, parse_mode='Markdown'):
        """Telegramにメッセージを送信"""
        url = f'{self.base_url}/sendMessage'
        payload = {
            'chat_id': self.chat_id,
            'text': text,
            'parse_mode': parse_mode
        }
        
        try:
            response = requests.post(url, json=payload, timeout=10)
            return response.status_code == 200
        except Exception as e:
            print(f"Telegramへの送信中のエラー: {e}")
            return False

def monitor_proxy_with_telegram():
    """Telegramで通知を伴う監視"""
    api = ProxyAPIClient()
    notifier = TelegramNotifier()
    
    try:
        balance = api.get_balance()
        
        # メッセージの生成
        message = f"""
📊 *プロキシ統計* ({datetime.now().strftime('%H:%M %d.%m.%Y')})

💰 残高: ${balance['balance']:.2f}
📈 使用された: {balance['traffic_used_gb']:.2f} GB
📉 残り: {balance['traffic_remaining_gb']:.2f} GB
🔌 アクティブなプロキシ: {balance['active_proxies']}
        """
        
        # クリティカル閾値のチェック
        if balance['traffic_remaining_gb'] < 5:
            message += "\n⚠️ *クリティカルにトラフィックが不足しています!*"
            notifier.send_message(message)
        elif balance['traffic_remaining_gb'] < 10:
            message += "\n⚡ トラフィックの補充をお勧めします"
            notifier.send_message(message)
        
        return balance
        
    except Exception as e:
        error_msg = f"❌ *プロキシ監視中のエラー*\n\n{str(e)}"
        notifier.send_message(error_msg)
        raise

# 監視の開始
monitor_proxy_with_telegram()

Slackとの統合

import requests
import json

class SlackNotifier:
    def __init__(self, webhook_url):
        self.webhook_url = webhook_url
    
    def send_alert(self, title, message, level='warning'):
        """Slackに通知を送信"""
        color = {
            'info': '#36a64f',
            'warning': '#ff9900',
            'critical': '#ff0000'
        }.get(level, '#cccccc')
        
        payload = {
            'attachments': [{
                'color': color,
                'title': title,
                'text': message,
                'footer': 'Proxy Monitor',
                'ts': int(datetime.now().timestamp())
            }]
        }
        
        try:
            response = requests.post(
                self.webhook_url,
                data=json.dumps(payload),
                headers={'Content-Type': 'application/json'},
                timeout=10
            )
            return response.status_code == 200
        except Exception as e:
            print(f"Slackへの送信中のエラー: {e}")
            return False

def check_proxy_health():
    """通知付きプロキシの健康チェック"""
    api = ProxyAPIClient()
    slack = SlackNotifier(os.getenv('SLACK_WEBHOOK_URL'))
    
    balance = api.get_balance()
    proxies = api.get_all_proxies()
    
    # 状態の分析
    offline_proxies = [p for p in proxies if p['status'] != 'active']
    
    if len(offline_proxies) > 0:
        message = f"非アクティブなプロキシが {len(offline_proxies)} 件見つかりました:\n"
        for proxy in offline_proxies[:5]:  # 最初の5件
            message += f"- {proxy['ip_address']} ({proxy['country']})\n"
        
        slack.send_alert(
            '非アクティブなプロキシ',
            message,
            level='warning'
        )
    
    if balance['traffic_remaining_gb'] < 5:
        slack.send_alert(
            'トラフィックがクリティカルに不足しています!',
            f"残り {balance['traffic_remaining_gb']:.2f} GB. "
            f"残高: ${balance['balance']:.2f}",
            level='critical'
        )

check_proxy_health()

自動補充の設定

一部のプロバイダーは、APIを通じて統計を取得するだけでなく、閾値に達した際に自動的に残高を補充することも可能です:

def auto_topup_if_needed(threshold_gb=10, topup_amount_usd=100):
    """残高が低い場合に自動的に補充"""
    api = ProxyAPIClient()
    
    balance = api.get_balance()
    
    if balance['traffic_remaining_gb'] < threshold_gb:
        print(f"トラフィックが閾値 ({threshold_gb} GB) を下回っているため、補充を開始します...")
        
        # APIを通じて補充リクエスト
        topup_response = requests.post(
            f'{api.base_url}/billing/topup',
            headers={'Authorization': f'Bearer {api.api_key}'},
            json={
                'amount': topup_amount_usd,
                'payment_method': 'card',
                'auto_topup': True
            },
            timeout=10
        )
        
        if topup_response.status_code == 200:
            print(f"✅ 残高が ${topup_amount_usd} 補充されました")
            
            # 通知の送信
            notifier = TelegramNotifier()
            notifier.send_message(
                f"💳 自動補充\n\n"
                f"金額: ${topup_amount_usd}\n"
                f"以前のトラフィック: {balance['traffic_remaining_gb']:.2f} GB\n"
                f"理由: 閾値 {threshold_gb} GB に達しました"
            )
        else:
            print(f"❌ 補充エラー: {topup_response.text}")
    else:
        print(f"トラフィックは十分です: {balance['traffic_remaining_gb']:.2f} GB")

# チェックの開始(cronに追加可能)
auto_topup_if_needed()

独自の統計ダッシュボードの作成

APIからのデータを視覚化するために、トラフィック消費、国別およびプロキシタイプ別のグラフを持つウェブダッシュボードを作成できます。Flask + Chart.jsを使用した簡単な例を見てみましょう。

Flaskによるバックエンド

from flask import Flask, jsonify, render_template
from datetime import datetime, timedelta
import requests

app = Flask(__name__)

class ProxyDashboard:
    def __init__(self):
        self.api_key = os.getenv('PROXY_API_KEY')
        self.base_url = 'https://api.proxyprovider.com/v1'
    
    def get_dashboard_data(self):
        """ダッシュボード用のすべてのデータを取得"""
        headers = {'Authorization': f'Bearer {self.api_key}'}
        
        # 残高と全体の統計
        balance = requests.get(
            f'{self.base_url}/balance',
            headers=headers
        ).json()
        
        # 過去30日間の履歴
        end_date = datetime.now()
        start_date = end_date - timedelta(days=30)
        
        history = requests.get(
            f'{self.base_url}/traffic/history',
            headers=headers,
            params={
                'from': start_date.strftime('%Y-%m-%d'),
                'to': end_date.strftime('%Y-%m-%d'),
                'group_by': 'day'
            }
        ).json()
        
        # プロキシのリスト
        proxies = requests.get(
            f'{self.base_url}/proxies/list',
            headers=headers
        ).json()
        
        # データの集約
        traffic_by_country = {}
        traffic_by_type = {}
        
        for proxy in proxies.get('proxies', []):
            country = proxy.get('country', 'Unknown')
            proxy_type = proxy.get('proxy_type', 'Unknown')
            traffic = proxy.get('traffic_used_mb', 0) / 1024  # GB単位
            
            traffic_by_country[country] = traffic_by_country.get(country, 0) + traffic
            traffic_by_type[proxy_type] = traffic_by_type.get(proxy_type, 0) + traffic
        
        return {
            'balance': balance,
            'history': history.get('daily_stats', []),
            'traffic_by_country': traffic_by_country,
            'traffic_by_type': traffic_by_type,
            'total_proxies': len(proxies.get('proxies', []))
        }

dashboard = ProxyDashboard()

@app.route('/')
def index():
    """ダッシュボードのメインページ"""
    return render_template('dashboard.html')

@app.route('/api/stats')
def get_stats():
    """統計を取得するためのAPIエンドポイント"""
    try:
        data = dashboard.get_dashboard_data()
        return jsonify(data)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, port=5000)

グラフ付きのフロントエンド (dashboard.html)

<!DOCTYPE html>
<html>
<head>
  <title>プロキシ統計ダッシュボード</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; }
    .stats-card { background: white; padding: 20px; margin: 10px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
    .stat-value { font-size: 2rem; font-weight: bold; color: #2563eb; }
    .chart-container { height: 300px; margin: 20px 0; }
  </style>
</head>
<body>
  <h1>📊 プロキシ統計ダッシュボード</h1>
  
  <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
    <div class="stats-card">
      <div>残高</div>
      <div class="stat-value" id="balance">-</div>
    </div>
    <div class="stats-card">
      <div>残りのトラフィック</div>
      <div class="stat-value" id="traffic-remaining">-</div>
    </div>
    <div class="stats-card">
      <div>使用された</div>
      <div class="stat-value" id="traffic-used">-</div>
    </div>
    <div class="stats-card">
      <div>アクティブなプロキシ</div>
      <div class="stat-value" id="active-proxies">-</div>
    </div>
  </div>

  <div class="chart-container">
    <canvas id="trafficChart"></canvas>
  </div>

  <script>
    async function fetchData() {
      const response = await fetch('/api/stats');
      const data = await response.json();
      document.getElementById('balance').innerText = data.balance.balance.toFixed(2);
      document.getElementById('traffic-remaining').innerText = data.balance.traffic_remaining_gb.toFixed(2);
      document.getElementById('traffic-used').innerText = data.balance.traffic_used_gb.toFixed(2);
      document.getElementById('active-proxies').innerText = data.balance.active_proxies;

      const labels = data.history.map(day => day.date);
      const trafficData = data.history.map(day => day.traffic_gb);

      const ctx = document.getElementById('trafficChart').getContext('2d');
      new Chart(ctx, {
        type: 'line',
        data: {
          labels: labels,
          datasets: [{
            label: 'トラフィック消費 (GB)',
            data: trafficData,
            borderColor: 'rgba(38, 99, 235, 1)',
            backgroundColor: 'rgba(38, 99, 235, 0.2)',
            fill: true,
          }]
        },
        options: {
          responsive: true,
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }

    fetchData();
  </script>
</body>
</html>
```