Netkeibaのスクレイピング制限についての整理

Python

はじめに

Netkeibaをスクレイピングする際には、通信制限を避けるための注意が必要です。通信制限が設けられる理由や基準、通信制限の解除ルール/回避方法、Pythonでのスクレイピング実装時のポイントについて解説します。について解説します。

スクレイピングを行う際には、利用規約を遵守し、サービス運営に支障をきたさないよう心掛けることが重要です。

スクレイピング制限(通信制限)の目的

通信制限が設けられる主な理由は、サーバの負荷を軽減するためです。
サーバは、クライアントからのリクエストに応じて負荷がかかります。リクエストの数が増えるほど、サーバの負担は大きくなり、通常利用している他のユーザーに影響を与えることがあります。

サーバ負荷を解消するために、サーバスペックを増強する(スケールアップやスケールアウト)ことも可能ですが、その分、運用コストが増加します。そのため、サービス提供側は通信制限を導入することで、負荷をコントロールします。

スクレイピング制限(通信制限)の基準

Netkeibaの公式ページでは、スクレイピングに関する注意事項が記載されています。

データベースの閲覧ができない・通信制限がかかった(スクレイビングについて) – よくある質問

スクレイピングによって多数のリクエスト(アクセス)を確認し、弊社サービスに対して支障があると判断した場合は、予告なく通信制限をかけさせていただくことがございます。
その場合、解除のご依頼をいただきましても解除できかねますこと、ご了承ください。

具体的なリクエスト数の基準については明示されていませんが、「多数のリクエスト」が制限の対象であることが明記されています。

通信制限の影響と仕組み

通信制限の影響

通信制限がかかると、Netkeibaのデータページにアクセスできなくなります。

通信制限により、上記URLへの接続がブロックされるため、データ収集ができなくなります。

検証結果から分かったこと

サービス運営に支障をきたさない基準を確認するために、いくつかの検証を実施しました。通信制限については、以下のような仕組みであると推測しています。

  • 通信制限の対象
    制限がかかると「データベース」にアクセスできなくなります。
  • リクエスト上限の単位
    通信制限は1時間ごとにリクエスト数の上限が設けられていると考えられます。
  • 制限解除のタイミング
    制限は24時間で自動解除されます。
  • 接続元IPの管理
    通信制限は接続元のグローバルIPアドレスによって制御されています。接続元IPを変更することで、制限を回避できます。

通信制限の回避方法(接続元グローバルIPの変更方法)

スクレイピングを行う際には、利用規約を遵守し、サービス運営に支障をきたさないよう心掛けることが重要です。

検証を行うにあたり、リクエスト上限を超えてしまい通信制限を受けました。2024年12月の時点だと、24時間後には通信制限は解除されました。ただ、今後も24時間後に解除されるとは限りません。通信制限を受けた場合、接続元グローバルIPを変更することで、通信制限を回避できます。

接続元のグローバルIPを変更する方法として、VPNサービスの利用が効果的です。ここでは、NordVPNを利用した方法をご紹介します。

  1. NordVPNをインストール
    NordVPNアプリをダウンロード・インストールします。
  2. アプリを起動
    アプリを起動し、「クイック接続」を選択します。これにより、負荷の少ないVPNサーバに自動的に接続されます。
  3. 接続元IPの変更
    接続元IPが変更され、NetkeibaからはVPNサーバのIPアドレスでアクセスしているように認識されます。

 

スクレイピングを行う際は、サイトの利用規約を必ず確認し、適切な方法で実施してください。過度な負荷をかけることは、サービス全体に影響を及ぼす可能性があることを忘れないでください。

Pythonでスクレイピングを行う際のポイント

User-Agentの設定

Netkeibaの場合、User-Agentを設定しないリクエストは、HTTPステータスコード400(Bad Request)を返されます。これは、サービス側がBotや不審なアクセスを拒否するためのセキュリティ対策です。適切なUser-Agentを設定することで、この問題を防ぐことができます。

User-Agentを用いたサンプルコード

import requests
import random
import time

# User-Agentリスト
user_agent = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0",
]

# ヘッダー設定
headers = {
    "User-Agent": random.choice(user_agent),
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
}

# リトライ処理を含むリクエスト関数
def fetch_url(url, max_retries=5, retry_delay=2):
    retries = 0
    while retries < max_retries:
        try:
            res = requests.get(url, headers=headers)
            res.raise_for_status()  # ステータスコードがエラーの場合に例外を発生
            return res
        except requests.exceptions.RequestException as e:
            print(f"Error: {e}. Retrying in {retry_delay} seconds...")
            retries += 1
            time.sleep(retry_delay)
    print("Max retries reached. Returning None.")
    return None

# 使用例
url = "https://xxx.yyy.com"
response = fetch_url(url)
if response:
    print("Request succeeded!")
else:
    print("Failed to fetch the URL.")

注意事項

通信制限の回避方法やスクレイピングについて解説しましたが、Netkeibaの利用規約を遵守し、サービス運営に支障をきたさないよう心掛けてください。

次回の記事について

Netkeibaから過去のレース結果を取得するプログラムを作成していました。今回の調査結果を踏まえてプログラムを更新し、紹介したいと思います。

以上です。

コメント

タイトルとURLをコピーしました