モデルとアービングリサーチのためのスポーツブックオッズのスクレイピング方法

オッズは秒単位で変動し、クリーンなデータはHTMLにはなく、スポーツブックのフロントエンドが呼び出す内部JSONにあります。これをポーリングし、ブック間で正規化し、ブロックされずに行う方法を紹介します。

スポーツブックオッズは、ほとんどの人がスクレイピングしようとする中で最も速く動く公開データです。ラインは秒単位で変動し、古い数字は誤った数字です。モデルを構築する人やアービトラージを研究する人にとっての良いニュースは、スコアボードHTMLを解析する必要がほとんどないことです。すべての最新のスポーツブックフロントエンドは内部JSON APIによって供給されており、そこにクリーンで構造化されたオッズが存在します。このガイドでは、これらのAPIからスポーツブックオッズをスクレイピングする方法、役立つ速度でポーリングする方法、ブック間で正規化する方法、そしてブロックされずに行う方法を説明します。

内部オッズAPIを見つける

ブラウザの開発者ツールでネットワークタブを開き、スポーツブックのイベントページを開き、XHR/Fetchでフィルタリングしてリクエストを監視します。イベント、マーケット、価格を返すJSONエンドポイントが表示されます。これはページがレンダリングするのと同じデータですが、構造化されています。10以上の北米およびオーストラリアのブック(DraftKings、BetMGM、Caesars、BetRivers、PointsBetなど)をカバーするコミュニティスクレイパーはすべてこの方法で動作します。HTMLを解析するのではなく、非公開の内部APIを呼び出します。なぜなら、JSONは安定していて完全だからです。一度読めば、1つのリクエストでイベントのすべてのマーケットを取得できます。

import requests

proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}

# endpoint + params come from watching the site's own network calls
API = "https://sportsbook.example.com/api/v2/events/{event_id}/markets"

def get_markets(event_id):
    r = requests.get(API.format(event_id=event_id), proxies=proxies,
                     timeout=15, headers={"User-Agent": "Mozilla/5.0"})
    return r.json()  # events -> markets -> selections with prices
内部JSON APIを見つけ、ブックを正規化し比較するスポーツブックオッズスクレイピングループの図
フロントエンドのJSON APIがクリーンなソースです - ポーリングし、毎サイクルページを再レンダリングしないでください。

速くポーリングするが、愚かにしない

モデルトレーニングには、1分ごとのスナップショットで十分です。4時間のウィンドウで60秒ごとにマネーラインをポーリングする公共のMLBスクレイパーは、合理的な参照ケイデンスです。ライブアービトラージリサーチにはよりタイトなポーリングが必要ですが、単一のIPからのタイトなポーリングは、まさにブックが監視するシグネチャです。答えは負荷を分散することです:各サイクルで出口IPを回転させ、単一のアドレスがエンドポイントを叩かないようにします。すべてを10進オッズに正規化し、選択ごとに1行にすることで、ブックを直接比較可能にします。

import time

def american_to_decimal(a):
    return round(1 + (a/100 if a > 0 else 100/abs(a)), 4)

def snapshot(event_id):
    rows = []
    for m in get_markets(event_id)["markets"]:
        for sel in m["selections"]:
            rows.append({
                "ts": time.time(),
                "market": m["name"],
                "runner": sel["name"],
                "decimal": american_to_decimal(sel["priceAmerican"]),
            })
    return rows

# poll on a steady interval; a rotating gateway gives a fresh IP each loop
while True:
    save(snapshot("mlb-12345"))
    time.sleep(60)

回転する住宅ゲートウェイを使用すると、これがワンライナーになります。すべてのリクエストを1つのエンドポイントに向けると、自動的に新しいIPが提供されるため、毎分のポーリングが1台のマシンのように見えません。フローが短期間に同じIPを必要とする場合 - 例えば、セッションにバインドされたマーケット - スティッキーセッションに切り替えます。スティッキーセッションと回転セッションのガイドでは、それぞれがどのように適合するかを説明しています。

オッズデータ用の回転する住宅IPを取得する

地理的ライセンスもデータ問題です

スポーツベッティングは管轄ごとにライセンスされているため、ブックが表示するオッズ - そしてそれがあなたにサービスを提供するかどうか - はリクエストがどこから来るかに依存します。ニュージャージーのDraftKingsラインは、他の州の同じマーケットとは異なる可能性があり、一部のブックは完全に地理的にブロックされます。それは単なるコンプライアンスの詳細ではなく、データを変えます。地域をまたいでベンチマークやアービングを行う場合、プロキシの出口を研究しているマーケットに固定し、実際のベッターがそこにいる場合に見えるオッズを取得します。QuantumProxiesは200以上の国と米国の州をカバーしているため、地域に正確なラインをローカルマシンのラックなしで取得できます。同じ地理的原則を運賃に適用したロケーションベースのスクレイピングガイドをご覧ください。

ラインの動きをクエリ可能にするためにオッズを保存する

オッズデータは、その履歴に関して質問できる場合にのみ役立ちます。そのため、初日から時系列として保存します。上書きするのではなく、すべてのスナップショットを追加し、ブック、マーケット、選択、タイムスタンプごとに1行にします。これにより、キックオフ前に価格がどのように変動したか(ラインの動き)を計算し、多くのブックが一緒にシフトする(スチームムーブ)を検出し、実際に利用可能だったオッズに対してモデルをバックテストすることができます。最新の価格のみを上書きすると、データセット全体で最も価値のあるシグナルを捨ててしまいます。

2つの実用的な注意点。まず、解析時ではなくキャプチャ時にタイムスタンプを記録し、各行に出口の場所を記録します - オッズは地域ごとに異なるため、「DraftKings, NJ, 14:32:05」は他の州の同じブックとは異なるデータポイントです。次に、タイムアウト後のリトライリクエストが価格を二重にカウントしないように、自然キー(ブック + マーケット + 選択 + タイムスタンプ)で重複を排除します。この構造により、クロスマーケットのエッジを比較するのが簡単なクエリになり、アービングやモデリングの研究がクリーンで監査可能な履歴に基づいて実行されます。これは、在庫の再入荷と可用性の監視ガイドが在庫に適用するのと同じ監視規律です - ここでは値が秒単位で動きます。

ボットウォールとAPIに頼るべき時

すべてのブックが同じように簡単ではありません。いくつかは強力なボット検出の背後にあり、単純なスクレイパーをすぐにブロックします。他のものは単に遅く、マーケットグループごとに1つのリクエストを強制します。ターゲットが重いJavaScriptの後にのみオッズをレンダリングする場合や、指紋認証で戦う場合、生のリクエストでは十分ではありません。Scraper APIは、実際のブラウザ指紋を持ち、IPを回転させ、必要に応じてJSをレンダリングするため、スタックを自分で維持するよりも手間が少なく、解析されたペイロードを返します。法的側面について1行:分析のために公開オッズをスクレイピングすることは一般的ですが、スポーツブックの利用規約は自動化されたアクセスをしばしば禁止しており、活動は規制されています - これはガイダンスであり、賭けや法的アドバイスではないため、あなたの管轄で確認してください。

効果的なスポーツブックオッズスクレイピングの実践をスクレイパーがブロックされるパターンと比較するチェックリスト
ブックは単一IPのバーストと無視された地理的ブロックを監視しています - 回転させ、地理を一致させ、ペースを調整してブロックされないようにします。

よくある質問

Pythonでベッティングオッズをスクレイピングするにはどうすればよいですか?

スポーツブックのネットワークタブを監視して、フロントエンドが呼び出す内部JSON APIを見つけ、それをプロキシを通じて直接リクエストし、構造化されたレスポンスを解析します。すべてを10進オッズに正規化し、選択ごとに1行にすることで、ブックを比較可能にします。これは、常に変化するレンダリングされたスコアボードHTMLを解析するよりもはるかに安定しています。

オッズをどのくらいの頻度でポーリングすべきですか?

モデルトレーニングには、通常30〜60秒ごとで十分です。一般的な参照は、毎分のマネーラインスナップショットです。アービトラージリサーチにはよりタイトな間隔が必要ですが、1つのIPからの高速ポーリングはフラグが立ちます - 出口IPを住宅プールで各サイクルごとに回転させ、負荷を1つのアドレスではなく多くのアドレスに分散させます。

なぜ他の場所からスクレイピングするとオッズが異なるのですか?

スポーツブックは管轄ごとにライセンスされているため、ラインと可用性は州や国によって異なり、一部のブックは完全に地理的にブロックされます。リクエストの出口場所がどのマーケットを表示するかを決定します。地域に正確なオッズを収集するには、プロキシの出口を研究している管轄に固定し、1つのグローバルな価格が存在すると仮定しないでください。

スポーツブックオッズのスクレイピングは合法ですか?

分析のために公開されているオッズを収集することは広く行われていますが、スポーツブックの利用規約は自動化されたアクセスをしばしば禁止しており、スポーツベッティングは地域ごとに厳しく規制されています。データを公開研究の入力として扱い、各サイトの利用規約とrobots指令を尊重し、あなたが活動する場所の規則を確認してください。これは一般的なガイダンスであり、法的または賭けのアドバイスではありません。

オッズをうまくスクレイピングするには、4つのステップに集約されます:内部JSONを読み、安定したケイデンスでポーリングし、住宅IPを回転させてアドレスが目立たないようにし、出口の地理をマーケットに合わせます。これらを正しく行えば、クリーンで地域に正確なオッズフィードを得ることができ、モデルやエッジハンティングリサーチの原材料となります。

Scraper APIでオッズを大規模に収集する