プロキシ B、またプロキシ B、その次にプロキシ A。ログは不審に見えますが、ランダム選択はまさにそう振る舞うことが許されています。

リクエストごとに同じリストから選ぶと、重複が起こり得ます。同じ確率のエンドポイントが 二つある場合、次の独立した選択が前回と一致する確率は 二分の一 です。重複を含む短い系列は、選択がリストを無視した証拠にはなりません。

本当に必要な挙動を選ぶ

要件選択ルール
毎回の選択が独立している毎回、対象リストから選ぶ
最初からやり直す前に各エンドポイントを 一度使うコピーをシャッフルして使い切り、次の周回を始める
直前のエンドポイントを避ける選ぶ前にそのエンドポイントを除外する

最後のポリシーでは、エンドポイントが 1 つだけの場合を明示的に扱います。

candidates = [endpoint for endpoint in eligible if endpoint != previous]
if not candidates:
    raise RuntimeError("No different eligible proxy is available")
selected = random.choice(candidates)

この断片は random がインポートされ、エンドポイントのリストがすでに検証済みであることを前提としています。公開プールは、プロトコルが最終的なクライアントに合う場合に無料プロキシリストから始められます。この選択ルールは依然として重複を制御します。待つ、唯一のエンドポイントを再利用する、停止するのいずれを選ぶかはアプリケーションのポリシーです。異なるランダム値を待ち続ける無限ループは、異なる選択肢が 一つしかないリストを解決できません。

並行ディスパッチャーでは、前のエンドポイントの選択と記録にも協調的な所有権が必要です。そうでなければ、二つのワーカーがどちらも古い値を除外し、同じ次の値を選ぶ可能性があります。

最後に、このルールはエンドポイントの同一性に関するものです。二つの異なるエンドポイントが一つの公開出口につながることがあり、一つのプロバイダーのエンドポイントが複数の出口につながることもあります。ローテーションが壊れていると判断する前に、それらを別々に記録してください。

関連記事