Discordは、自動化やボットに対して積極的に対抗しており、高度な検出システムを使用しています:IPアドレスの分析、行動パターン、レート制限。モデレーション、招待の配信、サーバー内のアクションの自動化のためにボットを立ち上げる場合、適切に設定されたプロキシがないと、作業開始から数時間でブロックされる可能性があります。このガイドでは、Discordに適したプロキシ、IPのローテーションの設定方法、プラットフォームの保護メカニズムの回避方法について説明します。
なぜDiscordはボットをブロックするのか、保護の仕組み
Discordは、自動化からの保護のために多層的なシステムを使用しており、複数のパラメータを同時に分析しています。プラットフォームは単に1つのIPからのリクエスト数をチェックするだけでなく、各接続の行動プロファイルを構築し、それを通常のユーザーのパターンと比較します。
Discordにおけるボット検出の主なメカニズム:
- レート制限 — Discordは、単位時間あたりのアクション数に厳しい制限を設けています。たとえば、1アカウントから5秒間に5メッセージ、1分間に50リクエストを超えることはできません。制限を超えると、一時的なブロック(HTTP 429)が発生します。
- IPアドレスの分析 — 1つのIPから複数のボットが動作している場合や疑わしい活動(アカウントの迅速な切り替え、大量のアクション)が見られると、DiscordはそのIPアドレス全体を数時間または数日間ブロックすることがあります。
- 接続のフィンガープリンティング — プラットフォームは技術的なパラメータを分析します:User-Agent、リクエストヘッダー、ライブラリのバージョン、応答時間。これらのパラメータが通常のDiscordクライアントと一致しない場合、そのアカウントは疑わしいとマークされます。
- 行動分析 — Discordは行動パターンを追跡します:あまりにも早い反応、メッセージ間の理想的な間隔、アクションのランダム性の欠如。厳格なアルゴリズムに従って動作するボットは、より早く特定されます。
プロキシなしでの典型的なブロックシナリオ:
- 1つの家庭用IPから3-5ボットを起動 — 作業開始から2-6時間後にIPがブロックされる
- サーバーへの招待の大量配信 — 10-15の招待を送信した時点でアカウントとIPが禁止される
- 自動モデレーション(メッセージの削除、役割の付与) — 1つのIPから1時間に100アクションを超えるとブロックされる
- サーバーのメンバーのパース — 200-300のプロファイルをスキャンした後に発見されて禁止される
プロキシは、異なるIPアドレス間でリクエストを分散させ、異なる場所の通常のユーザーのように見せることでこれらの問題を解決します。しかし、プロキシの種類を正しく選択し、ローテーションを設定することが重要です — 不適切な設定は、さらに早い禁止につながる可能性があります。
Discordボットに適したプロキシの種類
プロキシの種類の選択は、ボットの数、リクエストの頻度、予算、必要な匿名性のレベルに依存します。ここでは、Discordに適した3つの主要なプロキシの種類とその用途を見ていきましょう。
| プロキシの種類 | 利点 | 欠点 | 適している用途 |
|---|---|---|---|
| データセンターのプロキシ | 高速(ping 10-50 ms)、低価格($1-3/ IP/月)、安定性 | DiscordはデータセンターのIPを簡単に認識し、大量のアクションを行うとブロックされるリスクが高い | テスト、軽い自動化(1-2ボット)、大量のリクエストを伴わないタスク |
| 住宅用プロキシ | 実際の家庭ユーザーのIP、ブロックのリスクが最小限、大規模なアドレスプール(数百万のIP) | 平均速度(ping 100-300 ms)、高価格($5-15/ GBのトラフィック)、一部のIPの不安定性 | 大量の配信、サーバーのパース、5つ以上のボットでの作業、長期プロジェクト |
| モバイルプロキシ | モバイルキャリアのIP(4G/5G)、Discordからの最大の信頼、動的IPの切り替え | 高価格($50-150/ IP/月)、小さなアドレスプール、接続の切断の可能性 | 重要なアカウント、厳しいブロックの回避、高価値のアカウントでの作業 |
さまざまなタスクに対する選択の推奨:
モデレーションとサーバー管理(1-3ボット): 固定IPの住宅用プロキシ。1ボット=1 IP、ローテーションなし。これにより、Discordが通常の管理者ユーザーとして認識する安定した接続プロファイルが作成されます。
大量配信と招待(10以上のボット): 5-10分ごとにローテーションする住宅用プロキシ。負荷を分散させる:1つのIPから1時間に20アクションを超えないようにします。10ボット用に50以上のIPアドレスのプールを使用します。
メンバーとサーバーのパース: 1-3分ごとにローテーションする住宅用プロキシまたはモバイルプロキシ。パースは最もリスクの高いアクティビティの1つであり、Discordはスキャンパターンを簡単に計算します。リクエスト間にランダムな遅延(30-120秒)を使用します。
テストと開発: データセンターのプロキシは機能のデバッグに十分です。しかし、プロダクションに移行する前に、必ず住宅用プロキシに切り替えてください — Discordの動作は異なるIPタイプによって大きく異なる可能性があります。
重要な点:Discordは特定の国や地域からのIPアドレスに対して特に厳格です。ロシア、中国、ベトナム、インドからのIPは、スパマーの高い活動のためにより厳しいチェックを受けます。ターゲットオーディエンスがアメリカやヨーロッパにいる場合は、これらの地域のプロキシを使用してください — これにより、ブロックの可能性が40-60%減少します。
プロキシを通じてDiscordのレート制限を回避する方法
Discordのレート制限は、単位時間あたりのAPIリクエスト数に対する制限です。これには、グローバル(アプリ全体に対して)とper-route(特定のエンドポイントに対して)の2種類があります。プロキシは異なるIP間で負荷を分散させるのに役立ちますが、制限を無視できるというわけではありません — Discordはボットのトークンレベルでのアクティビティを追跡しています。
Discord APIの主なレート制限:
- メッセージの送信: 1チャンネルあたり5メッセージを5秒ごとに、ボット全体で10秒あたり50メッセージ
- チャンネルの作成/削除: 10分あたり50リクエスト
- メンバーの役割の変更: 10リクエストを10秒ごとに
- メンバーリストの取得: 1秒あたり1リクエスト(最も厳しい制限)
- DM(ダイレクトメッセージ)の送信: 5 DMを5秒ごとに、知らないユーザーへの大量配信でブロックされる
制限を超えると、DiscordはHTTP 429(リクエストが多すぎます)を返し、Retry-Afterヘッダーで待機時間を秒単位で示します。この応答を正しく処理することが重要です。
プロキシを使用したレート制限回避戦略:
# レート制限時のプロキシローテーションのPython例(discord.py)
import discord
from discord.ext import commands
import aiohttp
import asyncio
import random
class ProxyRotator:
def __init__(self, proxy_list):
self.proxies = proxy_list # ['http://user:pass@ip:port', ...]
self.current_index = 0
self.failed_proxies = set()
def get_next_proxy(self):
# 動作しないプロキシをスキップ
available = [p for p in self.proxies if p not in self.failed_proxies]
if not available:
self.failed_proxies.clear() # 完全なサイクルの後にリセット
available = self.proxies
proxy = available[self.current_index % len(available)]
self.current_index += 1
return proxy
def mark_failed(self, proxy):
self.failed_proxies.add(proxy)
# 初期化
proxy_rotator = ProxyRotator([
'http://user1:pass1@192.168.1.1:8080',
'http://user2:pass2@192.168.1.2:8080',
# ... 安定した動作のために10-20のプロキシを追加
])
intents = discord.Intents.default()
bot = commands.Bot(command_prefix='!', intents=intents)
async def send_with_retry(channel, message, max_retries=3):
"""レート制限の自動処理を伴うメッセージ送信"""
for attempt in range(max_retries):
try:
# 各試行で新しいプロキシを取得
proxy = proxy_rotator.get_next_proxy()
# Discord.pyは内部でaiohttpを使用しているため、プロキシを設定
connector = aiohttp.TCPConnector()
async with aiohttp.ClientSession(connector=connector) as session:
bot.http.connector = connector
bot.http.proxy = proxy
await channel.send(message)
return True
except discord.HTTPException as e:
if e.status == 429: # レート制限
retry_after = e.retry_after if hasattr(e, 'retry_after') else 5
print(f"レート制限! {retry_after}秒待機し、プロキシを変更します...")
# プロキシを一時的に使用不可としてマーク
proxy_rotator.mark_failed(proxy)
# 遅延にランダム性を追加
await asyncio.sleep(retry_after + random.uniform(1, 3))
else:
print(f"送信エラー:{e}")
await asyncio.sleep(2)
return False
@bot.event
async def on_ready():
print(f'ボットが起動しました:{bot.user}')
# 使用例
@bot.command()
async def mass_send(ctx):
channels = ctx.guild.text_channels[:5] # 最初の5つのチャンネル
for channel in channels:
success = await send_with_retry(channel, "テストメッセージ")
if success:
print(f"{channel.name}に送信されました")
# チャンネル間のランダムな遅延
await asyncio.sleep(random.uniform(3, 7))
レート制限を回避するための重要な原則:
- HTTP 429を常に処理する: Retry-Afterヘッダーを無視しないでください。Discordは再違反時にブロック時間を延長します(5秒から60秒以上へ)。
- ランダム性を追加する: リクエスト間の遅延はランダムであるべきです(例えば、固定の3秒ではなく2-5秒)。これは人間の行動を模倣します。
- 負荷を分散させる: 10ボットと20プロキシがある場合、各ボットに2プロキシを割り当ててローテーションします。すべてのボットに1つのプロキシを使用しないでください。
- プロキシの品質を監視する: 一部のIPはすでにDiscordによってブロックされている可能性があります。403または429を継続的に受け取るプロキシを自動的に除外します。
さまざまなタスクのためのIPローテーション戦略
プロキシのローテーションは、単にN分ごとにIPを変更することではありません。正しい戦略は、ボットのアクティビティのタイプとDiscordの接続の安定性に対する要件に依存します。ここでは、4つの主要なアプローチを見ていきましょう。
1. 固定IP(ローテーションなし)
使用するタイミング: モデレーションボット、サーバー管理ボット、音楽ボット、サーバーに常に存在するボット。
ロジック: 1ボット=1 IPアドレス(数週間、数ヶ月)。Discordはこの接続を通常の管理者ユーザーとして認識し、常に同じ場所からログインしていると見なします。
設定:
# Python (discord.py) - 固定プロキシ
import discord
from discord.ext import commands
PROXY = 'http://username:password@192.168.1.100:8080'
intents = discord.Intents.default()
bot = commands.Bot(command_prefix='!', intents=intents, proxy=PROXY)
# このボットのすべてのリクエストにプロキシが使用されます
bot.run('YOUR_BOT_TOKEN')
利点: 最大の安定性、IPによるブロックのリスクが最小、簡単な設定。
欠点: IPがブロックされた場合、手動でプロキシを変更し、ボットのセッションを再作成する必要があります。
2. 時間によるローテーション
使用するタイミング: 配信ボット、適度なアクティビティのボット(1時間あたり10-50アクション)、低頻度のデータパース。
ロジック: IPはリクエスト数に関係なく、5-15分ごとにタイマーで変更されます。これは、インターネットに再接続するユーザーを模倣します(たとえば、動的IPを持つモバイルインターネット)。
推奨インターバル:
- 低アクティビティ(5-10アクション/時):10-15分ごとにローテーション
- 中アクティビティ(20-40アクション/時):5-7分ごとにローテーション
- 高アクティビティ(50以上のアクション/時):2-3分ごとにローテーション + レート制限時の追加ローテーション
# JavaScript (discord.js) - 時間によるローテーション
const { Client, GatewayIntentBits } = require('discord.js');
const HttpsProxyAgent = require('https-proxy-agent');
const proxies = [
'http://user1:pass1@ip1:port',
'http://user2:pass2@ip2:port',
'http://user3:pass3@ip3:port',
];
let currentProxyIndex = 0;
function getProxyAgent() {
const proxy = proxies[currentProxyIndex];
currentProxyIndex = (currentProxyIndex + 1) % proxies.length;
return new HttpsProxyAgent(proxy);
}
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
rest: { agent: getProxyAgent() }
});
// 5分ごとにローテーション
setInterval(() => {
console.log('プロキシを変更します...');
client.rest.setAgent(getProxyAgent());
}, 5 * 60 * 1000);
client.login('YOUR_BOT_TOKEN');
3. リクエスト数によるローテーション
使用するタイミング: 大量のパース、サーバーメンバーのスクレイピング、自動招待。
ロジック: N回のリクエスト実行後にIPが変更されます(たとえば、20-50リクエストごと)。これにより、負荷が均等に分散され、1つのIPからのアクション数に対する見えないDiscordの制限を超えないようにします。
推奨N値:
- メンバーのパース:30-50リクエスト/ IP(スキャンパターンの発見を避けるため)
- DMの送信:10-15メッセージ/ IP(Discordは大量のDMに特に厳しい)
- 招待の作成:20-30招待/ IP
4. エラー時の適応型ローテーション
使用するタイミング: 重要なボット、高価値アカウントでの作業、厳しいブロックの回避。
ロジック: 429(レート制限)、403(禁止)、またはタイムアウトのエラーを受け取ったときに自動的にIPが変更されます。システムは「悪い」IPを記憶し、一時的にローテーションから除外します。
# Python - ブラックリストを使用した適応型ローテーション
import time
from collections import defaultdict
class AdaptiveProxyRotator:
def __init__(self, proxies):
self.proxies = proxies
self.current = 0
self.error_count = defaultdict(int)
self.blacklist_until = {} # {proxy: timestamp}
def get_proxy(self):
now = time.time()
# ブラックリストのプロキシをフィルタリング
available = [
p for p in self.proxies
if p not in self.blacklist_until or self.blacklist_until[p] < now
]
if not available:
# すべてがブラックリストにある場合、リセットして待機
print("すべてのプロキシがブラックリストにあります。60秒待機します...")
time.sleep(60)
self.blacklist_until.clear()
available = self.proxies
proxy = available[self.current % len(available)]
self.current += 1
return proxy
def report_error(self, proxy, error_type):
self.error_count[proxy] += 1
# 多数のエラーが発生した場合、一時的にブロック
if self.error_count[proxy] >= 3:
blacklist_duration = 300 # 5分
self.blacklist_until[proxy] = time.time() + blacklist_duration
print(f"プロキシ {proxy} がブラックリストに追加されました。{blacklist_duration}秒間")
self.error_count[proxy] = 0 # カウンターをリセット
def report_success(self, proxy):
# 成功したリクエスト - エラーカウンターをリセット
if proxy in self.error_count:
self.error_count[proxy] = max(0, self.error_count[proxy] - 1)
推奨される組み合わせアプローチ: 基本的な時間によるローテーション(5-10分ごと) + エラー時の適応型ローテーションを使用してください。これにより、安定性と問題への迅速な対応が確保されます。
人気のライブラリでのプロキシ設定:discord.pyとdiscord.js
Discordボットを作成するための最も人気のある2つのライブラリでのプロキシ設定をステップバイステップで見ていきます。これらの例はほとんどのタスクに適しており、あなたのニーズに簡単に適応できます。
Discord.py(Python)
Discord.pyはHTTPリクエストにaiohttpを使用しています。プロキシは、クライアントの作成時にproxyパラメータを介して設定するか、HTTPセッションを直接設定することで設定できます。
ステップ1:依存関係のインストール
pip install discord.py aiohttp aiohttp-socks
# aiohttp-socksはSOCKS5プロキシに必要ですが、HTTP/HTTPSには必須ではありません
ステップ2:1つのプロキシでの基本設定
import discord
from discord.ext import commands
# プロキシのフォーマット:protocol://username:password@ip:port
PROXY = 'http://user:pass@192.168.1.100:8080'
intents = discord.Intents.default()
intents.message_content = True # メッセージを読むため
bot = commands.Bot(
command_prefix='!',
intents=intents,
proxy=PROXY # すべてのHTTPリクエストのためのプロキシ
)
@bot.event
async def on_ready():
print(f'ボット {bot.user} がプロキシを介して接続されました!')
@bot.command()
async def ping(ctx):
await ctx.send(f'ポン! レイテンシ:{round(bot.latency * 1000)}ms')
bot.run('YOUR_BOT_TOKEN')
ステップ3:プロキシのローテーション設定
import discord
from discord.ext import commands, tasks
import aiohttp
import random
PROXIES = [
'http://user1:pass1@ip1:port',
'http://user2:pass2@ip2:port',
'http://user3:pass3@ip3:port',
]
class ProxyBot(commands.Bot):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.current_proxy = random.choice(PROXIES)
self.proxy_rotation.start()
@tasks.loop(minutes=5) # 5分ごとにローテーション
async def proxy_rotation(self):
old_proxy = self.current_proxy
self.current_proxy = random.choice([p for p in PROXIES if p != old_proxy])
# 新しいプロキシでHTTPセッションを再作成
await self.http.close()
connector = aiohttp.TCPConnector(limit=0)
self.http.connector = connector
self.http.__session = aiohttp.ClientSession(connector=connector)
print(f'プロキシが変更されました:{old_proxy} -> {self.current_proxy}')
async def close(self):
self.proxy_rotation.cancel()
await super().close()
intents = discord.Intents.default()
bot = ProxyBot(command_prefix='!', intents=intents)
bot.run('YOUR_BOT_TOKEN')
Discord.js(Node.js)
Discord.jsはプロキシの組み込みサポートがないため、https-proxy-agentまたはsocks-proxy-agentライブラリが使用されます。
ステップ1:依存関係のインストール
npm install discord.js https-proxy-agent
# SOCKS5用:npm install socks-proxy-agent
ステップ2:基本設定
const { Client, GatewayIntentBits } = require('discord.js');
const { HttpsProxyAgent } = require('https-proxy-agent');
const PROXY = 'http://user:pass@192.168.1.100:8080';
const agent = new HttpsProxyAgent(PROXY);
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
],
rest: { agent: agent } // REST APIリクエストのためのプロキシ
});
client.on('ready', () => {
console.log(`ボット ${client.user.tag} がプロキシを介して接続されました!`);
});
client.on('messageCreate', async (message) => {
if (message.content === '!ping') {
await message.reply(`ポン! WebSocketのレイテンシ:${client.ws.ping}ms`);
}
});
client.login('YOUR_BOT_TOKEN');
ステップ3:プロキシのローテーション
const { Client, GatewayIntentBits } = require('discord.js');
const { HttpsProxyAgent } = require('https-proxy-agent');
const PROXIES = [
'http://user1:pass1@ip1:port',
'http://user2:pass2@ip2:port',
'http://user3:pass3@ip3:port',
];
let currentProxyIndex = 0;
function getNextProxy() {
const proxy = PROXIES[currentProxyIndex];
currentProxyIndex = (currentProxyIndex + 1) % PROXIES.length;
return new HttpsProxyAgent(proxy);
}
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
rest: { agent: getNextProxy() }
});
// 10分ごとにローテーション
setInterval(() => {
const newAgent = getNextProxy();
client.rest.setAgent(newAgent);
console.log('プロキシが変更されました');
}, 10 * 60 * 1000);
client.on('ready', () => {
console.log(`ボット ${client.user.tag} が起動しました`);
});
client.login('YOUR_BOT_TOKEN');
重要: WebSocket接続(リアルタイムイベントの取得用)は、常にプロキシをサポートしているわけではありません。WebSocket接続に問題がある場合は、REST APIリクエスト用のHTTPプロキシのみを使用し、WebSocketはプロキシなしで使用してください。重要なケースでは、WebSocket接続のためにプロキシの代わりにVPNの使用を検討してください。
一般的な間違いとその回避方法
正しく設定されたプロキシでも、一般的な間違いを犯すと禁止される可能性があります。ここでは、最も重要な間違いとその解決策を見ていきましょう。
間違い1:すべてのボットに同じプロキシを使用する
問題: 5-10ボットを1つのIPアドレスで起動しています。Discordは、1つのIPから複数のアカウントの同時アクティビティを検出し、すべてのアカウントとIPをブロックします。
解決策: 安定した動作のために「1ボット=1ユニークIP」のルールを守ります。10ボットがある場合は、最低10の異なるプロキシを使用します。重要なプロジェクトの場合は、ローテーション用に50-100%の余裕(10ボットに対して15-20プロキシ)を追加します。
間違い2:IPのローテーションが早すぎる
問題: IPを30-60秒ごとに変更し、ブロックを回避できると考えています。実際には、Discordは頻繁なIPの変更を疑わしい活動として認識します — 通常のユーザーは毎分インターネットに再接続しません。
解決策: 最小ローテーション間隔は3-5分です。最適は、リクエストの強度に応じて5-15分です。例外は、レート制限(429)を受け取ったときの適応型ローテーションです。
間違い3:プロキシの地理的位置を無視する
問題: ボットはアメリカのサーバーに存在しますが、ロシア、中国、インドのプロキシを使用しています。Discordはサーバーの位置とIPアドレスの不一致を検出し、疑わしさを高めます。
解決策: Discordサーバーやターゲットオーディエンスがいる国/地域のプロキシを使用します。国際的なプロジェクトの場合は、アメリカやヨーロッパのプロキシを選択してください — これらはDiscordでの評判が良いです。
間違い4:エラー処理がない
問題: ボットがHTTP 429(レート制限)を受け取り、リクエストを続けてしまいます。これにより、状況が悪化します。Discordは試行ごとにブロック時間を延長します。
解決策: 常にエラーコードを処理します:
- 429(リクエストが多すぎます): Retry-Afterヘッダーを読み、指定された時間+1-3秒待機します。プロキシを変更します。
- 403(禁止): IPまたはトークンがブロックされています。プロキシを変更し、トークンの有効性を確認します。
- 401(未認証): ボットのトークンが無効です。Discord Developer Portalでトークンを確認します。
- 502/504(ゲートウェイエラー): プロキシまたはDiscord APIに問題があります。10-30秒待機し、プロキシを変更します。
間違い5:パブリックまたは安価なプロキシを使用する
問題: 無料または安価なプロキシ($0.5-1/ IP)は、すでにDiscordによってブロックされていることが多く、他の多くのボットやスパマーによって使用されています。
解決策: 信頼できるプロバイダーからの高品質の住宅用プロキシに投資します。使用前にIPの評判を確認します(AbuseIPDB、IPQualityScoreなどのサービス)。$5-10の高品質のプロキシ1つは、$1のブロックされたプロキシ10個よりも優れています。
間違い6:すべてのボットに同じUser-Agentを使用する
問題: すべてのボットがライブラリの標準User-Agent(たとえば、「DiscordBot(discord.py 2.0)」)を使用しています。Discordはこのような接続を簡単にグループ化し、大量の自動化を検出します。
解決策: ボット間でUser-Agentを変化させます。現実的な値を使用します:
# Python - カスタムUser-Agent
import discord
class CustomBot(discord.Client):
async def request(self, *args, **kwargs):
# User-Agentをオーバーライド
if 'headers' not in kwargs:
kwargs['headers'] = {}
kwargs['headers']['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Discord/1.0.9015'
return await super().request(*args, **kwargs)
ボットの動作監視とエラー処理
正しい監視により、問題が大規模な禁止につながる前に発見できます。ここでは、プロキシを介したDiscordボットの動作を追跡するための重要なメトリックとツールを見ていきましょう。
追跡するメトリック
| メトリック | 追跡する内容 | 重要な値 |
|---|---|---|
| 429エラーの頻度 | 時間あたりのレート制限エラーの数 | >10/時 — リクエスト戦略を見直してください |
| 403エラーの頻度 | IPまたはトークンのブロック | >3/日 — プロキシが危険にさらされています |
| レイテンシ(遅延) | プロキシ + Discord APIの応答時間 | >1000ms — 遅いプロキシ、交換してください |
| リクエストの成功率 | 成功したリクエストの割合(HTTP 200-299) | <85% — プロキシまたはボットのロジックに問題があります |
| プロキシの稼働時間 | 問題なくプロキシが使用されている時間 | <24時間 — IPがブロックされた可能性があります |
ログシステムの例
# Python - メトリックを使用した高度なロギング
import logging
import time
from collections import defaultdict
import json
class BotMonitor:
def __init__(self):
self.metrics = {
'requests_total': 0,
'requests_success': 0,
'errors_429': 0,
'errors_403': 0,
'errors_other': 0,
'proxy_switches': 0,
'avg_latency': []
}
self.proxy_stats = defaultdict(lambda: {
'requests': 0,
'errors': 0,
'last_error': None
})
# ロガーの設定
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('bot_monitor.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger('BotMonitor')
def log_request(self, proxy, status_code, latency):
self.metrics['requests_total'] += 1
self.metrics['avg_latency'].append(latency)
self.proxy_stats[proxy]['requests'] += 1
if 200 <= status_code < 300:
self.metrics['requests_success'] += 1
elif status_code == 429:
self.metrics['errors_429'] += 1
self.proxy_stats[proxy]['errors'] += 1
self.logger.warning(f'プロキシ {proxy} でレート制限が発生しました')
elif status_code == 403:
self.metrics['errors_403'] += 1
self.proxy_stats[proxy]['errors'] += 1
self.proxy_stats[proxy]['last_error'] = time.time()
self.logger.error(f'プロキシ {proxy} がブロックされました(403)')
else:
self.metrics['errors_other'] += 1
self.logger.error(f'プロキシ {proxy} でエラー {status_code} が発生しました')
def log_proxy_switch(self, old_proxy, new_proxy):
self.metrics['proxy_switches'] += 1
self.logger.info(f'プロキシが変更されました:{old_proxy} -> {new_proxy}')
def get_report(self):
total = self.metrics['requests_total']
if total == 0:
return "データがありません"
success_rate = (self.metrics['requests_success'] / total) * 100
avg_latency = sum(self.metrics['avg_latency']) / len(self.metrics['avg_latency'])
report = f"""
=== ボット監視レポート ===
総リクエスト数:{total}
成功数:{self.metrics['requests_success']} ({success_rate:.1f}%)
429エラー(レート制限):{self.metrics['errors_429']}
403エラー(ブロック):{self.metrics['errors_403']}
その他のエラー:{self.metrics['errors_other']}
平均レイテンシ:{avg_latency:.0f}ms
プロキシの切り替え:{self.metrics['proxy_switches']}
=== プロキシ統計 ===
"""
for proxy, stats in self.proxy_stats.items():
error_rate = (stats['errors'] / stats['requests'] * 100) if stats['requests'] > 0 else 0
report += f"{proxy}: {stats['requests']} リクエスト、 {stats['errors']} エラー ({error_rate:.1f}%)\n"
return report