Pythonでプロキシを回転させる方法

Pythonでプロキシローテーションをマスターして、IPバンを克服し、ウェブスクレイピングプロセスを効率化しましょう。
4 分読
How to Rotate Proxies in Python blog image

このガイドでは、Pythonでプロキシを回転させる方法について学びます:

  • プロキシとは何か、なぜ使うのか
  • プロキシローテーションとは何か?
  • Pythonでプロキシを回転させる方法
  • Pythonでプロキシを回転させる場合の一般的な制限

さあ、飛び込もう!

代理人とは何か?

プロキシとは、インターネット上でユーザーとネットワークリソースの仲介をするサーバーのことである。つまり、プロキシは当事者間のリクエストと応答を転送する 仲介者であると考えることができる。

なぜPythonでプロキシを使うのか?

プロキシを使ってウェブサイトにリクエストを送信すると、リクエストはまずプロキシサーバーを経由します。その後、プロキシはあなたのリクエストをウェブサイトに転送し、レスポンスを受信してあなたに送り返します。このプロセスにより、あなたのIPアドレスが送信先にマスクされ、リクエストがあなたのデバイスではなくプロキシサーバーから来ているように見せかけることができます。

プロキシを使いたい典型的な理由は、ウェブリクエストの自動化やウェブスクレイピングの場合である。このシナリオでは、Pythonは、その豊富なライブラリと大規模で活発なコミュニティのおかげで、Webスクレイピングに最適な言語の1つです。

プロキシ・ローテーションとは何か?

1つのIPアドレスからのリクエストが多すぎると、ウェブサイトはレート制限や完全なIP禁止によってあなたをブロックするかもしれません。そこで、プロキシによるプロキシローテーションが役立ちます。

ウェブリクエストを行う際に、異なるプロキシサーバーを系統的に切り替えることは、IPアドレスローテーションを実施する最良の方法の一つです。この手順は、一般的なアンチスクレイピング技術を回避するのに役立ち、次のような利点があります:

  • IPブロックの回避複数のIPにリクエストを分散させることで、ウェブサイトによるスクレイピング行為の検出やブロックを困難にします。
  • レート制限の回避:ウェブサイトは多くの場合、特定の時間枠内でIPアドレスごとのリクエスト制限を設定している。プロキシをローテーションすることで、1つのIPでこれらの制限に達した後でもスクレイピングを続けることができます。
  • 地域制限のあるコンテンツへのアクセス:ウェブサイトによっては、地域によって表示されるコンテンツが異なります。さまざまな国のプロキシでプロキシローテーションを行うことで、地域限定のコンテンツにアクセスすることができます。

Pythonでプロキシを回転させる方法:3つのアプローチ

プロキシとは何か、なぜプロキシを回転させるのかがわかったところで、Pythonによるステップバイステップのチュートリアルの準備をしよう。次の段落では、Pythonでプロキシを回転させる方法を、さまざまなアプローチやライブラリを用いて紹介します。

すべてのスクリプトのターゲット・サイトは、HTTPBinプロジェクトの/ipエンドポイントになる。この特別なエンドポイントは呼び出し元のIPアドレスを返すので、サーバーが見ているIPが回転しているかどうかをテストするのに最適である。

Pythonでプロキシを回転させる時間だ!

必要条件

Pythonでプロキシを回転させるチュートリアルを再現するには、Python 3.7以降がマシンにインストールされている必要があります。

前提条件

プロジェクトのメインフォルダーをproxy_rotation/と呼ぶとする。このステップが終わると、フォルダは以下のような構造になっている:

proxy_rotation/
    ├── requests_file.py
    ├── async.py
    ├── scrapy_rotation/
    └── venv/ 

どこでだ:

  • requests.pyと async.pyはそれぞれRequestsとAIOHTTPのプロキシローテーションロジックを格納するPythonファイルです。
  • scrapy_rotation/はScrapyプロジェクトを含むフォルダです。あなたは後でそれを作成し、インスタンス化します。
  • venv/には仮想環境が含まれています。

venv/ 仮想環境ディレクトリは次のように作成する:

python -m venv venv

アクティベートするには、ウィンドウズで以下を実行する:

venv\Scripts\activate

同様に、macOSとLinuxでは、以下を実行する:

source venv/bin/activate

最後の前提条件として、プロキシのリストを取得する必要がある。この記事では、無料のプロキシリストを使用することができます。

PythonでRequestsを使ってプロキシをローテーションする方法

このチュートリアルでは、Python でRequests を使ってプロキシを回転させる方法を学びます。

ステップ #1: 依存関係のインストール

有効化された仮想環境に、Requestsをインストールする:

pip install requests

ステップ2:回転ロジックの定義

PythonでRequestsを使ってプロキシをローテートするには、以下のコードをrequests_file.pyファイルに記述します:

import random
import requests

# Define a list of proxies and return a random one
def get_random_proxy():
    proxies = [
        "http://PROXY_1:PORT_X",
        "http://PROXY_2:PORT_Y",
        "http://PROXY_3:PORT_X",
        # Add more proxies here...
    ]

    # Randomly pick a proxy
    return random.choice(proxies)

for i in range(3):
    proxy_url = get_random_proxy()
    proxies = {
        "http": proxy_url,
        "https": proxy_url,
    }
    response = requests.get("https://httpbin.io/ip", proxies=proxies)
    print(response.text)

どこでだ:

  • get_random_proxy()関数は、取得したプロキシのリストを保存し、random.choice()メソッドでランダムなプロキシを返します。
  • forループはプロキシのランダムなリストを繰り返し、requests.get()メソッドで実際のリクエストを行います。より詳しい情報はPython Requests でプロキシを使うガイド を読んでください。

ステップ3:スクリプトの起動

スクリプトを起動するには、以下を実行する:

python requests_file.py

以下は予想される反応である:

{
  "origin": "PROXY_3:PORT_K"
}
{
  "origin": "PROXY_1:PORT_N"
}
{
  "origin": "PROXY_2:PORT_P"
}

すばらしい!スクリプトの終了IPが希望通りにローテーションされました。

PythonでAIOHTTPを使ってプロキシをローテーションする方法

Requestsライブラリを使ったランダム化手法の主な制限は、一度に一つのプロキシを使うことである。つまり、次のプロキシが使われる前に、それぞれの リクエストが終了するのを待つ必要があるということである。

この制限を避けるために、AIOHTTPを使うことができる。このライブラリを使うと、非同期リクエストを行うことができ、 複数のプロキシを同時にノンブロッキングで使うことができる。言い換えれば、ターゲットサーバーに非同期の並列リクエストを行うことで、リストからプロキシをローテーションすることができます。非同期ウェブスクレイピングのガイドでAIOHTTPの動作をご覧ください。

以下のセクションでは、PythonでAIOHTTPを使ってプロキシをローテーションする方法を示します。

ステップ #1: 依存関係のインストール

仮想環境を起動し、AIOHTTPをインストールする:

pip install aiohttp

ステップ2:回転ロジックの定義

PythonでAIOHTTPを使ってプロキシを回転させるには、async.pyファイルに以下のコードを記述します:

import asyncio
import aiohttp

# Define a list of proxies
proxies_list = [
    "http://PROXY_1:PORT_X",
    "http://PROXY_2:PORT_Y",
    "http://PROXY_3:PORT_X",
    # Add more proxies here...
]

async def fetch_ip(session, proxy_address, attempt):
    print(f"Attempt {attempt} using proxy: {proxy_address}")
    async with session.get("https://httpbin.io/ip", proxy=proxy_address) as response:
        json_response = await response.json()
        print(f"Response from httpbin.io/ip (Attempt {attempt}):")
        print(f"IP Address: {json_response.get('origin', 'Unknown')}")
        print("-" * 40)
        return json_response

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = []
        num_attempts = 3
        for i in range(num_attempts):
            # Rotate proxies using the modulus operator.
            proxy_address = proxies_list[i % len(proxies_list)]
            tasks.append(fetch_ip(session, proxy_address, i + 1))
        # Run all requests concurrently
        await asyncio.gather(*tasks)

# Launch the script
asyncio.run(main())

このコードは次のようなものである:

  • fetch_ip()関数は、セッション、プロキシ、試行番号を受け取ってリクエストを管理する。特に、ターゲットのウェブサイトにGETリクエストを送り、レスポンスを表示します。
  • main()関数
    :Polylangプレースホルダを変更しない

ステップ3:スクリプトの起動

スクリプトを起動するには、以下を実行する:

python async.py

これが予想された反応だ:

Attempt 1 using proxy: http://PROXY_1:PORT_X
Attempt 2 using proxy: http://PROXY_2:PORT_Y
Attempt 3 using proxy: http://PROXY_3:PORT_Z

Response from httpbin.io/ip (Attempt 3):
IP Address: xxx.xxx.xxx.xxx
----------------------------------------
Response from httpbin.io/ip (Attempt 1):
IP Address: yyy.yyy.yyy.yyy
----------------------------------------
Response from httpbin.io/ip (Attempt 2):
IP Address: zzz.zzz.zzz.zzz
----------------------------------------

驚いた!IPは予想通りローテーションされている。

Python Scrapyでプロキシを回転させる方法

以前の記事でScrapy -rotating-proxyを使ってPythonでプロキシを回転させる可能性について説明した。

このガイドセクションでは、その方法を学ぶことができる!

ステップ #1: 依存関係のインストール

起動した仮想環境で、必要なライブラリをインストールする:

pip install scrapy scrapy-rotating-proxies

ステップ2:新しいScrapyプロジェクトを作成する

リポジトリのメインフォルダ(proxy_rotation/)内で、次のコマンドで新しいScrapyプロジェクトをインスタンス化します:

scrapy startproject scrapy_rotation

これにより、以下の構造を持つscrapy_rotation/という新しいサブフォルダが作成される:

scrapy_rotation/
  ├── scrapy_rotation/ 
  │   ├── __init__.py
  │   ├── items.py # Defines the data structure for scraped items
  │   ├── middlewares.py # Custom middlewares
  │   ├── pipelines.py # Handles post-processing of scraped data
  │   ├── settings.py # Project settings
  │   └── spiders/ # Folder for all spiders
  └── scrapy.cfg # Scrapy configuration file

メインフォルダ(proxy_rotation/)から scrapy_rotation/に移動する:

cd scrapy_rotation

これで、ターゲットのウェブサイトを指す新しいスパイダーを作成できる:

scrapy genspider rotation http://httpbin.io/ip

このスクリプトはまた、spiders/フォルダ内にrotation.pyファイルを作成します。

ステップ3:回転ロジックの定義

プロキシローテーションのロジックは、settings.pyファイルを以下の設定で変更することで管理できます:

# Enable the rotating proxies middleware
DOWNLOADER_MIDDLEWARES = {
    "rotating_proxies.middlewares.RotatingProxyMiddleware": 610,
    "rotating_proxies.middlewares.BanDetectionMiddleware": 620,
}

# List of proxies to rotate
ROTATING_PROXY_LIST = [
    "http://PROXY_1:PORT_X",
    "http://PROXY_2:PORT_Y",
    "http://PROXY_3:PORT_Z",
    # Add more proxies as needed
]

# Configure retry settings
RETRY_TIMES = 5  # Number of retries for failed requests
RETRY_HTTP_CODES = [500, 502, 503, 504, 408]  # HTTP codes to retry

ここでプロキシのローテーションを管理するのは、DOWNLOADER_MIDDLEWARESの rotating_proxy.middlewares.RotatingProxyMiddleware:610オプションである。特に、このオプションはROTATING_PROXY_LISTからプロキシを選択し、各リクエストに割り当てる。

また、rotating_proxyes.middlewares.BanDetectionMiddleware: 620オプションは、スクレイパーがIPがターゲットウェブサイトによって禁止またはブロックされているかどうかを検出することを可能にします。そのためにリクエストが失敗すると、ミドルウェアは新しいプロキシでリクエストを再試行します。そのため、このオプションはRotatingProxyMiddlewareと密接に連携して、禁止されたプロキシが自動的に回避されるようにします。

spiders/フォルダ内のrotation.pyに以下のように記述します:

import scrapy

class IpSpider(scrapy.Spider):
    name = "ip_spider"
    start_urls = ["http://httpbin.io/ip"]
    def parse(self, response):
        # Extract and print the IP address from the response
        ip = response.json().get("origin")
        self.log(f"IP Address: {ip}")

このクラスはスパイダー全体をインスタンス化し、リクエストごとにレスポンスを表示します。

ステップ4:スクリプトの起動

スクリプトを起動するには、IpSpider()クラスの名前(ip_spider)を使用する必要があります:

scrapy crawl ip_spider

ScrapyがCLIで返すデータは特に完全だ。そのため、すべてがうまくいった場合、他の情報の中に、次のようなものが見つかります:

2025-02-18 14:55:17 [rotating_proxies.expire] DEBUG: Proxy <http://PROXY_1:PORT_X> is GOOD
2025-02-18 14:55:17 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://httpbin.io/robots.txt> (referer: None)
2025-02-18 14:55:24 [rotating_proxies.middlewares] INFO: Proxies(good: 1, dead: 0, unchecked: 2, reanimated: 0, mean backoff time: 0s)

Pythonにおけるプロキシ・ローテーションの上記のアプローチの限界

上述のプロキシ回転法は便利だが、いくつかの制限がある:

  • プロキシのリストを手動で取得し、管理する必要がある。
  • これらは定型的なコードを含んでいる。
  • 高品質なプロキシサーバーを使用しなければ、IP禁止になる可能性があります。

Pythonでプロキシのローテーションをより効率的かつ効果的に処理する方法をお探しなら、Bright Dataは市場で最高のローテーションプロキシを提供しています。たった一つのプロキシURLで、HTTPクライアントやスクレイピングライブラリに組み込むことができます。これにより、定型的なコードや手動でのローテーション管理が不要になります。

このアプローチの主な利点は他にもある:

  • 設定可能なスティッキーIPによる自動IPローテーション
  • sc name=”num_rotating”]百万世帯IPへのアクセス
  • プロキシサーバー位置のジオロケーション制御
  • HTTP、HTTPS、SOCKSプロトコルのサポート

プロキシ管理を簡素化-自動回転プロキシをご覧ください!

結論

この記事では、3つの異なるライブラリを使ってPythonでプロキシを回転させる方法を学んだ:Requests、AIOHTTP、Scrapyです。上記のガイドセクションで示したように、このプロセスは複雑ではなく、数行のコードで済みます。

しかし、このアプローチにはいくつかの欠点がある:

  • コードは定型的なものが多く、スクリプトの保守性が低くなる。
  • 大規模なプロキシサーバーのリストを管理し、アクセスを提供する必要がある。

Pythonでプロキシを回転させるより効率的なソリューションです。

Bright Dataは、フォーチュン500社、20,000人以上の顧客にサービスを提供する、世界最高のプロキシサーバーを管理しています。その提供するプロキシの種類は多岐にわたります:

Bright Dataの無料アカウントを作成して、プロキシとスクレイピングソリューションをお試しください!

クレジットカードは必要ありません