ブログに戻る

Cloudflareの検出を回避するためのプロキシの使用方法

Cloudflareがプロキシを通じてあなたのリクエストをブロックしていますか?正しいTLS設定から、実際の例を用いたヘッドレスブラウザの使用まで、検出回避の技術的手法を解説します。

📅2025年12月17日
```html

プロキシを介してCloudflareの検出を回避するための7つの検証済みの方法

Cloudflareは全ウェブトラフィックの20%以上を処理し、ボットからの保護のための多層システムを使用しています。プロキシサーバーを介して作業する場合、CAPTCHAやブロックを受ける可能性が大幅に増加します。このガイドでは、2024年に機能する検出の技術的側面と回避の実践的な方法を解説します。

Cloudflareがプロキシとボットを特定する方法

Cloudflareは、各リクエストの数十のパラメータをチェックする包括的な分析システムを使用しています。検出メカニズムを理解することは、保護を成功裏に回避するための第一歩です。

主な検出方法

TLSフィンガープリンティング: CloudflareはSSL/TLSハンドシェイクのパラメータ(暗号スイート、拡張、順序)を分析します。各HTTPクライアントにはユニークな「フィンガープリント」があります。例えば、Pythonのrequestsは、ChromeやFirefoxとは異なる特有の暗号セットを使用するOpenSSLを利用します。

Cloudflareはリクエストを分析する際、TLSフィンガープリントを指定されたUser-Agentと照合します。Chrome 120を指定しているのに、TLSパラメータがPython requestsに一致する場合、これはボットの即時検出を意味します。

検証パラメータ 分析される内容 検出リスク
TLSフィンガープリント 暗号スイート、拡張、TLSバージョン 高い
HTTP/2フィンガープリント ヘッダーの順序、SETTINGSフレーム 高い
IP評判 IPの履歴、データセンターへの所属 中程度
JavaScriptチャレンジ JSの実行、canvasフィンガープリンティング、WebGL 高い
行動分析 リクエストパターン、タイミング、マウスの動き 中程度

2023年以降、Cloudflareは行動パターンを分析するために機械学習を積極的に使用しています。このシステムは、技術的なパラメータだけでなく、リクエスト間の時間間隔、ユーザーの行動の順序、マウスの動き、ページのスクロールを追跡します。

TLSフィンガープリントのマスキング

TLSフィンガープリンティングは、ボット検出の最も効果的な方法です。標準のHTTPクライアント(requests、curl、axios)は、実際のブラウザと混同できないフィンガープリントを生成します。解決策は、ブラウザのTLS動作を模倣する専門のライブラリを使用することです。

curl-impersonateの使用

curl-impersonateライブラリは、人気のあるブラウザのTLSおよびHTTP/2フィンガープリントを正確にコピーする修正されたcurlのバージョンです。Chrome、Firefox、Safari、Edgeをサポートしています。

# curl-impersonateのインストール
git clone https://github.com/lwthiker/curl-impersonate
cd curl-impersonate
make chrome-build

# Chrome 120を模倣して使用
curl_chrome120 -x http://username:password@proxy.example.com:8080 \
  -H "Accept-Language: en-US,en;q=0.9" \
  https://example.com

Python: tls-clientライブラリ

Pythonには、curl-impersonateを内部で使用し、requestsに似たインターフェースを提供するtls-clientというラッパーがあります。

import tls_client

# Chrome 120のフィンガープリントでセッションを作成
session = tls_client.Session(
    client_identifier="chrome_120",
    random_tls_extension_order=True
)

# プロキシの設定
proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

# リクエストの実行
response = session.get(
    'https://example.com',
    proxies=proxies,
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'DNT': '1',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1'
    }
)

print(response.status_code)

重要: tls-clientを使用する際は、ヘッダーのUser-Agentが選択したclient_identifierに一致することが重要です。不一致は即座に検出につながります。

TLSフィンガープリントの確認

パースを開始する前に、TLSフィンガープリントを確認することをお勧めします。tls.peet.wsja3er.comのサービスを使用して分析してください。

# フィンガープリントの確認
response = session.get('https://tls.peet.ws/api/all')
print(response.json()['tls']['ja3'])

# 実際のChromeのフィンガープリントと比較:
# https://kawayiyi.com/tls-fingerprint-database/

HTTPヘッダーの正しい設定

正しいTLSフィンガープリントがあっても、不正確なHTTPヘッダーはボットを示します。Cloudflareはヘッダーの存在だけでなく、その順序、値の形式、論理的一貫性も分析します。

Chrome用の必須ヘッダー

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-User': '?1',
    'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
    'Sec-Ch-Ua-Mobile': '?0',
    'Sec-Ch-Ua-Platform': '"Windows"',
    'Cache-Control': 'max-age=0'
}

Sec-Ch-Ua-*ヘッダーはChrome 89で登場し、Client Hints APIの一部です。現代のUser-Agentを使用する際にこれらが欠けていることは、ボットの明確な兆候です。

ヘッダーの順序が重要

HTTP/2では、各ブラウザに対してヘッダーの順序が固定されています。Pythonのrequestsや他の標準クライアントは、ヘッダーをアルファベット順に送信しますが、これはブラウザの動作とは異なります。カスタムヘッダー順序をサポートするライブラリを使用してください。

アドバイス:ブラウザのDevToolsを使用して(ネットワークタブ→リクエストを右クリック→コピー→cURLとしてコピー)実際のブラウザのヘッダーの正確なコピーを取得し、それをコードに適応させてください。

User-Agentの動的生成

すべてのリクエストに同じUser-Agentを使用すると、検出のリスクが高まります。最新のUser-Agentのプールを作成し、それをローテーションしてください。

import random

# 最新のUser-Agentプール(2024年12月)
USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
]

def get_random_headers():
    ua = random.choice(USER_AGENTS)
    
    # 選択したUAに基づいて他のヘッダーを適応
    if 'Chrome' in ua:
        return {
            'User-Agent': ua,
            'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120"',
            # ... 他のChromeヘッダー
        }
    elif 'Firefox' in ua:
        return {
            'User-Agent': ua,
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            # ... Firefoxヘッダー
        }
    # ... 他のブラウザの処理

ヘッドレスブラウザの使用

CloudflareがJavaScriptチャレンジや高度な検出を使用している場合、唯一の信頼できる回避方法は実際のブラウザです。ヘッドレスブラウザは自動的にJavaScript、クッキーを処理し、完全に認証されたフィンガープリントを生成します。

anti-detectパッチを使用したPlaywright

Playwrightは、Seleniumの現代的な代替手段であり、パフォーマンスが優れています。しかし、標準のPlaywrightはnavigator.webdriverや他のマーカーを介して簡単に検出されます。マスキングのためにplaywright-stealthを使用してください。

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

def bypass_cloudflare(url, proxy):
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=True,
            proxy={
                "server": f"http://{proxy['host']}:{proxy['port']}",
                "username": proxy['username'],
                "password": proxy['password']
            },
            args=[
                '--disable-blink-features=AutomationControlled',
                '--disable-dev-shm-usage',
                '--no-sandbox'
            ]
        )
        
        context = browser.new_context(
            viewport={'width': 1920, 'height': 1080},
            user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            locale='en-US',
            timezone_id='America/New_York'
        )
        
        page = context.new_page()
        stealth_sync(page)  # anti-detectパッチの適用
        
        # ページに移動
        page.goto(url, wait_until='networkidle', timeout=30000)
        
        # Cloudflareチャレンジの通過を待つ(通常5-10秒)
        page.wait_for_timeout(8000)
        
        # 成功した回避の確認
        if 'Just a moment' in page.content():
            print('Cloudflareチャレンジに失敗しました')
            return None
        
        # 今後の使用のためにクッキーを抽出
        cookies = context.cookies()
        html = page.content()
        
        browser.close()
        return {'html': html, 'cookies': cookies}

# 使用例
proxy_config = {
    'host': 'proxy.example.com',
    'port': 8080,
    'username': 'user',
    'password': 'pass'
}

result = bypass_cloudflare('https://example.com', proxy_config)

プラペティアエクストラとプラグイン

Node.jsエコシステムのための最良の解決策は、puppeteer-extraとpuppeteer-extra-plugin-stealthプラグインです。このプラグインは、30以上の異なる自動化マスキング技術を適用します。

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

puppeteer.use(StealthPlugin());

async function bypassCloudflare(url, proxyUrl) {
    const browser = await puppeteer.launch({
        headless: 'new',
        args: [
            `--proxy-server=${proxyUrl}`,
            '--disable-blink-features=AutomationControlled',
            '--window-size=1920,1080'
        ]
    });
    
    const page = await browser.newPage();
    
    // ビューポートとユーザーエージェントの設定
    await page.setViewport({ width: 1920, height: 1080 });
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    
    // navigator.webdriverのオーバーライド
    await page.evaluateOnNewDocument(() => {
        delete Object.getPrototypeOf(navigator).webdriver;
    });
    
    // ページに移動
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
    
    // チャレンジの通過を待つ
    await page.waitForTimeout(8000);
    
    // コンテンツとクッキーを取得
    const content = await page.content();
    const cookies = await page.cookies();
    
    await browser.close();
    
    return { content, cookies };
}

// 使用例
bypassCloudflare('https://example.com', 'http://user:pass@proxy.example.com:8080')
    .then(result => console.log('成功'))
    .catch(err => console.error(err));

パフォーマンス:ヘッドレスブラウザはリソースを大幅に消費します(インスタンスあたり200-500MBのRAM)。高負荷のタスクには、クッキーを取得するためだけに使用し、その後はこれらのクッキーを持つHTTPクライアントに切り替えることをお勧めします。

Cloudflare回避のためのプロキシの種類の選択

プロキシの種類は、回避の成功に重要な影響を与えます。CloudflareはデータセンターのIPアドレスのデータベースを保持し、それに対してより厳しい検証ルールを適用します。

プロキシの種類 回避の可能性 速度 コスト 推奨
データセンター 30-40% 高い 低い ヘッドレスブラウザとのみ使用
レジデンシャル 85-95% 中程度 高い 最適な選択
モバイル 90-98% 中程度 非常に高い 重要なタスク用
ISP(静的レジデンシャル) 80-90% 高い 中程度 価格と品質のバランス

なぜレジデンシャルプロキシが効果的なのか

レジデンシャルプロキシは、実際のデバイス(家庭用ルーター、スマートフォン)のIPアドレスを使用します。CloudflareはこのようなIPを大量にブロックすることができないため、通常のユーザーもブロックされてしまいます。統計によると、レジデンシャルIPはデータセンターよりも15-20倍少なくCAPTCHAを受けます。

レジデンシャルプロキシを使用する際には、ジオロケーションが重要です。ターゲットサイトが米国向けの場合、アジアのプロキシを使用すると疑わしさが増します。広範な地理的範囲を持ち、都市ごとのターゲティングが可能なプロバイダーを選択してください。

最大の信頼性のためのモバイルプロキシ

モバイルプロキシは、モバイルオペレーター(4G/5G)のIPアドレスを使用します。モバイルネットワークの特徴は、飛行機モードを介してIPが動的に変更されることで、ほぼ無限のクリーンなIPアドレスを提供します。モバイルIPがブロックされる可能性はほぼゼロです。

# APIを介したモバイルIPのローテーションの例
import requests
import time

def rotate_mobile_ip(proxy_api_url):
    """モバイルプロキシのIPを変更する"""
    response = requests.get(f"{proxy_api_url}/rotate")
    if response.status_code == 200:
        print("IPが正常に変更されました")
        time.sleep(5)  # 変更の適用を待つ
        return True
    return False

# モバイルプロキシを使用
mobile_proxy = "http://user:pass@mobile.proxy.com:8080"

for i in range(10):
    # リクエストの実行
    response = requests.get(
        'https://example.com',
        proxies={'http': mobile_proxy, 'https': mobile_proxy}
    )
    
    # 各リクエストの後にIPをローテーション
    rotate_mobile_ip('https://api.proxy.com/mobile')

クッキーとセッションの管理

Cloudflareチャレンジを成功裏に通過した後、サーバーはクッキー(cf_clearance、__cfduidなど)を設定し、クライアントの正当性を確認します。これらのクッキーを適切に管理することで、再検証を回避できます。

cf_clearanceの抽出と再利用

cf_clearanceクッキーは通常30-60分有効です。ヘッドレスブラウザを介して取得した後、通常のHTTPリクエストで使用できます。

import requests
import pickle
from datetime import datetime, timedelta

class CloudflareCookieManager:
    def __init__(self, cookie_file='cf_cookies.pkl'):
        self.cookie_file = cookie_file
        self.cookies = self.load_cookies()
    
    def load_cookies(self):
        """保存されたクッキーの読み込み"""
        try:
            with open(self.cookie_file, 'rb') as f:
                data = pickle.load(f)
                # 有効期限の確認
                if data['expires'] > datetime.now():
                    return data['cookies']
        except FileNotFoundError:
            pass
        return None
    
    def save_cookies(self, cookies, ttl_minutes=30):
        """TTL付きでクッキーを保存"""
        data = {
            'cookies': cookies,
            'expires': datetime.now() + timedelta(minutes=ttl_minutes)
        }
        with open(self.cookie_file, 'wb') as f:
            pickle.dump(data, f)
    
    def get_cf_clearance(self, url, proxy):
        """ブラウザを介してcf_clearanceを取得"""
        if self.cookies:
            return self.cookies
        
        # ここにブラウザを起動するコード(前のセクションから)
        # ...
        browser_cookies = bypass_cloudflare(url, proxy)['cookies']
        
        # requests形式に変換
        cookies_dict = {c['name']: c['value'] for c in browser_cookies}
        self.save_cookies(cookies_dict)
        self.cookies = cookies_dict
        
        return cookies_dict
    
    def make_request(self, url, proxy):
        """クッキーを自動的に管理するリクエスト"""
        cookies = self.get_cf_clearance(url, proxy)
        
        response = requests.get(
            url,
            cookies=cookies,
            proxies={'http': proxy, 'https': proxy},
            headers=get_random_headers()
        )
        
        # 再度チャレンジを受けた場合はクッキーを更新
        if response.status_code == 403 or 'cf-browser-verification' in response.text:
            print("クッキーが期限切れです。新しいクッキーを取得します...")
            self.cookies = None
            return self.make_request(url, proxy)
        
        return response

# 使用例
manager = CloudflareCookieManager()
response = manager.make_request(
    'https://example.com/api/data',
    'http://user:pass@proxy.example.com:8080'
)

IPアドレスへのクッキーのバインディング

Cloudflareはcf_clearanceをチャレンジを通過したIPアドレスにバインドします。このクッキーを別のIPで使用するとブロックされます。ローテーションプロキシを使用する場合は、各IPごとに別々のクッキーセットを保持する必要があります。

import hashlib

class IPBoundCookieManager:
    def __init__(self):
        self.cookies_by_ip = {}
    
    def get_ip_hash(self, proxy_url):
        """プロキシを識別するためのハッシュを生成"""
        return hashlib.md5(proxy_url.encode()).hexdigest()
    
    def get_cookies_for_proxy(self, proxy_url, target_url):
        """特定のプロキシ用のクッキーを取得"""
        ip_hash = self.get_ip_hash(proxy_url)
        
        if ip_hash in self.cookies_by_ip:
            cookies_data = self.cookies_by_ip[ip_hash]
            if cookies_data['expires'] > datetime.now():
                return cookies_data['cookies']
        
        # ブラウザを介して新しいクッキーを取得
        new_cookies = self.fetch_cookies_with_browser(target_url, proxy_url)
        
        self.cookies_by_ip[ip_hash] = {
            'cookies': new_cookies,
            'expires': datetime.now() + timedelta(minutes=30)
        }
        
        return new_cookies

プロキシのローテーションとリクエスト頻度の制御

正しい技術スタックがあっても、1つのIPからのリクエスト頻度が高すぎるとレート制限がトリガーされます。Cloudflareはトラフィックパターンを分析し、異常な活動を特定します。

プロキシローテーションの戦略

ローテーションには主に3つのアプローチがあります:ラウンドロビン(順次)、ランダム、スティッキーセッション(セッションへのバインディング)。Cloudflareを回避するには、IPごとのリクエスト制限を設けたスティッキーセッション戦略が最適です。

import time
import random
from collections import defaultdict
from datetime import datetime, timedelta

class SmartProxyRotator:
    def __init__(self, proxy_list, max_requests_per_ip=20, cooldown_minutes=10):
        self.proxy_list = proxy_list
        self.max_requests_per_ip = max_requests_per_ip
        self.cooldown_minutes = cooldown_minutes
        
        # 使用カウンター
        self.usage_count = defaultdict(int)
        self.last_used = {}
        self.cooldown_until = {}
    
    def get_proxy(self):
        """次の利用可能なプロキシを取得"""
        available_proxies = []
        
        for proxy in self.proxy_list:
            # クールダウンの確認
            if proxy in self.cooldown_until:
                if datetime.now() < self.cooldown_until[proxy]:
                    continue
                else:
                    # クールダウン後にカウンターをリセット
                    self.usage_count[proxy] = 0
                    del self.cooldown_until[proxy]
            
            # リクエスト制限の確認
            if self.usage_count[proxy] < self.max_requests_per_ip:
                available_proxies.append(proxy)
        
        if not available_proxies:
            # すべてのプロキシがクールダウン中の場合は待機
            wait_time = min(
                (self.cooldown_until[p] - datetime.now()).total_seconds()
                for p in self.cooldown_until
            )
            print(f"すべてのプロキシがクールダウン中です。{wait_time:.0f}秒待機します...")
            time.sleep(wait_time + 1)
            return self.get_proxy()
        
        # 使用が最も少ないプロキシを選択
        proxy = min(available_proxies, key=lambda p: self.usage_count[p])
        
        self.usage_count[proxy] += 1
        self.last_used[proxy] = datetime.now()
        
        # 制限に達した場合はクールダウンを設定
        if self.usage_count[proxy] >= self.max_requests_per_ip:
            self.cooldown_until[proxy] = datetime.now() + timedelta(
                minutes=self.cooldown_minutes
            )
            print(f"プロキシ {proxy} が制限に達しました。クールダウン {self.cooldown_minutes} 分。")
        
        return proxy
    
    def add_delay(self):
        """リクエスト間のランダムな遅延(人間の模倣)"""
        delay = random.uniform(2, 5)  # 2-5秒
        time.sleep(delay)

# 使用例
proxy_pool = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
    # ... 安定した動作のために50-100のプロキシまで
]

rotator = SmartProxyRotator(
    proxy_pool,
    max_requests_per_ip=15,  # 保守的な値
    cooldown_minutes=15
)

# リクエストの実行
for i in range(1000):
    proxy = rotator.get_proxy()
    
    response = requests.get(
        'https://example.com/page',
        proxies={'http': proxy, 'https': proxy},
        headers=get_random_headers()
    )
    
    print(f"リクエスト {i+1}: {response.status_code}")
    rotator.add_delay()

アダプティブレートリミティング

より高度なアプローチは、サーバーの応答に基づいてリクエストの頻度を動的に調整することです。429エラーやCAPTCHAが発生し始めた場合は、自動的にペースを落とします。

class AdaptiveRateLimiter:
    def __init__(self, initial_delay=3.0):
        self.delay = initial_delay
        self.min_delay = 1.0
        self.max_delay = 30.0
        self.success_streak = 0
        self.failure_streak = 0
    
    def on_success(self):
        """成功したリクエスト — 加速可能"""
        self.success_streak += 1
        self.failure_streak = 0
        
        if self.success_streak >= 10:
            # 遅延を10%減少
            self.delay = max(self.min_delay, self.delay * 0.9)
            self.success_streak = 0
    
    def on_failure(self, status_code):
        """エラー — 減速"""
        self.failure_streak += 1
        self.success_streak = 0
        
        if status_code == 429:  # レート制限
            # 積極的な減速
            self.delay = min(self.max_delay, self.delay * 2.0)
        elif status_code == 403:  # 可能なブロック
            self.delay = min(self.max_delay, self.delay * 1.5)
        
        print(f"遅延が {self.delay:.2f}s に増加しました")
    
    def wait(self):
        """次のリクエスト前の待機"""
        # ランダム性を追加 ±20%
        actual_delay = self.delay * random.uniform(0.8, 1.2)
        time.sleep(actual_delay)

回避のための既存のツールとライブラリ

ゼロから独自のソリューションを開発するには時間と専門知識が必要です。Cloudflareの回避プロセスを自動化するための既存のツールがあります。

cloudscraper(Python)

cloudscraperライブラリは、requestsの上に構築されており、JavaScriptチャレンジを自動的に解決します。基本的な保護には機能しますが、高度な検証には対処できない場合があります。

import cloudscraper

# プロキシサポート付きのスクレイパーを作成
scraper = cloudscraper.create_scraper(
    browser={
        'browser': 'chrome',
        'platform': 'windows',
        'desktop': True
    }
)

# プロキシの設定
proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

# リクエストの実行
response = scraper.get('https://example.com', proxies=proxies)

if response.status_code == 200:
    print("回避成功")
    print(response.text)
else:
    print(f"エラー: {response.status_code}")

FlareSolverr(ユニバーサル)

FlareSolverrは、Cloudflareのチャレンジを解決するためにヘッドレスブラウザを起動するプロキシサーバーです。HTTP APIを介して動作し、任意のプログラミング言語をサポートします。

# Dockerを介してFlareSolverrを起動
docker run -d \
  --name=flaresolverr \
  -p 8191:8191 \
  -e LOG_LEVEL=info \
  ghcr.io/flaresolverr/flaresolverr:latest

# Pythonからの使用
import requests

def solve_cloudflare(url, proxy=None):
    flaresolverr_url = "http://localhost:8191/v1"
    
    payload = {
        "cmd": "request.get",
        "url": url,
        "maxTimeout": 60000
    }
    
    if proxy:
        payload["proxy"] = {
            "url": proxy
        }
    
    response = requests.post(flaresolverr_url, json=payload)
    result = response.json()
    
    if result['status'] == 'ok':
        return {
            'html': result['solution']['response'],
            'cookies': result['solution']['cookies'],
            'user_agent': result['solution']['userAgent']
        }
    else:
        raise Exception(f"FlareSolverrエラー: {result['message']}")

# 使用例
result = solve_cloudflare(
    'https://example.com',
    proxy='http://user:pass@proxy.example.com:8080'
)

print(result['html'])

undetected-chromedriver

自動的に多くのanti-detect技術を適用する修正されたSelenium ChromeDriverのバージョンです。Playwrightよりも使いやすいですが、柔軟性は低いです。

import undetected_chromedriver as uc
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def bypass_with_uc(url, proxy):
    options = uc.ChromeOptions()
    options.add_argument(f'--proxy-server={proxy}')
    options.add_argument('--disable-blink-features=AutomationControlled')
    
    driver = uc.Chrome(options=options, version_main=120)
    
    try:
        driver.get(url)
        
        # Cloudflareチャレンジの消失を待つ
        WebDriverWait(driver, 20).until_not(
            EC.presence_of_element_located((By.ID, "cf-spinner-please-wait"))
        )
        
        # 信頼性のために追加の待機
        time.sleep(3)
        
        # 結果を取得
        html = driver.page_source
        cookies = driver.get_cookies()
        
        return {'html': html, 'cookies': cookies}
    
    finally:
        driver.quit()

# 使用例
result = bypass_with_uc(
    'https://example.com',
    'http://user:pass@proxy.example.com:8080'
)

組み合わせアプローチ:最適な戦略は、クッキーを初期取得するためにヘッドレスブラウザを使用し、その後はこれらのクッキーを持つHTTPクライアント(tls-client、cloudscraper)に切り替えることです。これにより、信頼性とパフォーマンスのバランスが得られます。

結論

プロキシを介してCloudflareを回避するには、包括的なアプローチが必要です:正しいTLSフィンガープリント、認証されたHTTPヘッダー、高品質のプロキシ、およびセッション管理の適切な実施。主な推奨事項は次のとおりです:

  • レジデンシャルまたはモバイルプロキシをデータセンターの代わりに使用する
  • 正しいTLSフィンガープリントを持つライブラリを使用する(tls-client、curl-impersonate)
  • 複雑な場合は、anti-detectパッチを持つヘッドレスブラウザを使用する
  • cf_clearanceクッキーを保存して再利用する
  • レート制限を考慮してプロキシをローテーションする(IPあたり15-20リクエスト以下)
  • リクエスト間にランダムな遅延を追加する(2-5秒)

Cloudflareの保護は常に進化しているため、ツールを定期的に更新し、戦略を適応させることが重要です。フィンガープリンティング技術の変化を監視し、最新の保護バージョンでソリューションをテストしてください。

安定した動作のためには、広範なIPプールと自動ローテーションを持つプロフェッショナルなプロキシサービスを使用することをお勧めします。

```