많은 프록시를 다루는 경우 — 중재, 파싱 또는 멀티 계정 관리 — 수동으로 트래픽 소비를 관리하는 것은 악몽이 됩니다. 프록시 제공업체의 API는 통계 수집을 자동화할 수 있게 해줍니다: 트래픽 잔액, 활성 세션, IP 주소별 소비 및 사용 이력. 이 가이드에서는 Python, Node.js 및 cURL 코드 예제를 통해 통계 관리를 위한 API 통합 방법을 설명합니다.
프록시 통계 자동화가 필요한 이유
다양한 프로젝트를 위해 10-50개의 프록시를 관리할 때, 제공업체의 개인 계정을 통해 잔액 및 트래픽 소비를 수동으로 확인하는 것은 비효율적입니다. API는 여러 가지 중요한 문제를 해결합니다:
API 통계의 주요 작업:
- 트래픽 잔액 모니터링 — 한계 도달 시 자동 알림
- 프로젝트별 소비 관리 — 고객 또는 작업 간 비용 분배
- 효율성 분석 — 어떤 프록시가 더 많은 트래픽을 소비하는지 및 그 이유
- 다운타임 방지 — 트래픽이 소진되기 전에 잔액 보충
- CRM/청구 통합 — 비즈니스 프로세스 내에서 프록시 비용 자동 관리
여러 계정을 통해 광고를 운영하는 중재자에게는 어떤 프록시가 활성화되어 있고 얼마나 많은 트래픽이 남아 있는지 아는 것이 매우 중요합니다 — 잔여 한도가 초과되어 갑작스럽게 차단되는 것은 수천 달러의 손실로 이어질 수 있습니다. Instagram이나 TikTok에서 고객 계정을 관리하는 SMM 에이전시에게는 자동화가 프록시 사용에 대한 정확한 청구서를 발행할 수 있게 해줍니다.
마켓플레이스 파서(Wildberries, Ozon, Avito)는 기본 프록시의 한도가 소진되면 자동으로 백업 프록시로 전환할 수 있습니다. API는 수동 개입 없이 24/7 작동하는 장애 조치 시스템을 구축할 수 있게 해줍니다.
프록시 제공업체 API 기본 사항
대부분의 현대 프록시 제공업체는 서비스 관리를 위한 RESTful API를 제공합니다. API는 표준 방식으로 작동합니다: 인증 매개변수를 포함하여 특정 엔드포인트에 HTTP 요청을 보내면 서버가 데이터가 포함된 JSON을 반환합니다.
| API 구성 요소 | 설명 | 예시 |
|---|---|---|
| 기본 URL | 제공업체의 API 기본 주소 | https://api.provider.com/v1 |
| 인증 | API 키 또는 Bearer Token | Authorization: Bearer YOUR_API_KEY |
| 엔드포인트 | 다양한 작업을 위한 특정 경로 | /statistics, /balance |
| 응답 형식 | 데이터 구조 | status, data, error 필드가 포함된 JSON |
| 요청 제한 | 분당 요청 수 제한 | 60-300 요청/분 |
프록시 제공업체의 API에서 반환되는 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를 사용할 때는 요청 제한(rate limits)을 고려하는 것이 중요합니다. 대부분의 제공업체는 분당 60-300 요청을 허용합니다. 통계 모니터링에는 이 정도면 충분합니다 — 일반적으로 요청은 5-15분마다 이루어집니다.
인증 및 API 키 받기
API 작업의 첫 번째 단계는 인증 키를 받는 것입니다. 제공업체마다 과정은 다르지만, 일반적인 논리는 동일합니다:
API 키를 받기 위한 단계별 안내:
- 프록시 제공업체의 개인 계정에 로그인합니다.
- "API" 또는 "설정" → "API 접근" 섹션을 찾습니다.
- "API 키 생성" 또는 "토큰 생성" 버튼을 클릭합니다.
- 키를 복사하여 안전한 장소에 저장합니다 (한 번만 표시됩니다).
- 제공업체가 IP 주소에 대한 바인딩을 요구하는 경우 IP 화이트리스트를 설정합니다.
- cURL 또는 Postman을 통해 테스트 요청으로 키를 확인합니다.
프록시 제공업체 API에서 인증하는 두 가지 주요 방법이 있습니다:
| 방법 | 작동 방식 | 헤더 예시 |
|---|---|---|
| Bearer Token | 토큰은 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
# 지난 주 통계 수집
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': '프록시 모니터',
'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 fetchStats() {
const response = await fetch('/api/stats');
const data = await response.json();
document.getElementById('balance').innerText = data.balance.balance;
document.getElementById('traffic-remaining').innerText = data.balance.traffic_remaining_gb;
document.getElementById('traffic-used').innerText = data.balance.traffic_used_gb;
document.getElementById('active-proxies').innerText = data.balance.active_proxies;
const ctx = document.getElementById('trafficChart').getContext('2d');
const labels = data.history.map(stat => stat.date);
const trafficData = data.history.map(stat => stat.traffic_gb);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: '일일 트래픽 소비 (GB)',
data: trafficData,
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 2,
fill: false
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
fetchStats();
</script>
</body>
</html>