この記事ではDevOps・自動化に特化して解説します。AI自動化・DevOps全般は AI自動化ツール完全ガイド2026|ノーコードからコードまで徹底比較 をご覧ください。

cloudscraperとは何か:Cloudflare保護サイトへのPythonアクセスを自動化する

cloudscraperは、CloudflareのアンチボットページをPythonから自動バイパスするモジュールで、GitHubで6,400以上のスターを獲得している。requestsライブラリの完全な上位互換として設計されており、既存のrequestsベースのスクレイピングコードを最小限の変更で対応させることができる。

Webスクレイピングの現場で最も頻繁に遭遇する障壁のひとつが、CloudflareのBot Management機能だ。Cloudflareは世界中のウェブサイトの約20%以上を保護しており、ボットアクセスを検知すると「I’m Under Attack Mode(IUAM)」ページを表示し、JavaScriptチャレンジを実行させる仕組みになっている。

通常のrequestsやurllib3ではJavaScriptを実行できないため、このチャレンジをパスできない。SeleniumやBrowser Useのような完全なブラウザ自動化ツールで対応する方法もあるが、オーバーヘッドが大きく、軽量なデータ収集処理には向かない。

cloudscraperはこの問題をJavaScriptインタープリターをPython内で実行することで解決する。js2py、Node.js、ChakraCoreなど複数のJSエンジンを内蔵しており、Cloudflareのチャレンジスクリプトを解析・実行してセッションクッキーを自動取得する。

cloudscraperが対応するChallenge種別

  • Cloudflare v1チャレンジ(旧形式JSチャレンジ)
  • Cloudflare v2チャレンジ(reCAPTCHAベース)
  • Cloudflare v3チャレンジ(現行の主流方式)
  • Turnstile CAPTCHA(2022年以降の新形式)
    各種チャレンジに対して自動検知・自動処理が動作する。

cloudscraperの技術アーキテクチャ:JSチャレンジ自動処理の仕組み

cloudscraperの動作フローは以下のように構成されている。

flowchart TD A["requests.get()相当の
HTTP リクエスト"] --> B{"Cloudflare検知?"} B -->|"通常のサイト"| C["レスポンス返却
(通常の requests と同じ)"] B -->|"Cloudflare保護サイト"| D["チャレンジページ
取得・解析"] D --> E{"チャレンジ種別
判定"} E -->|"JSチャレンジ v1/v2/v3"| F["JSインタープリター起動
js2py / Node.js / ChakraCore"] E -->|"Turnstile CAPTCHA"| G["CAPTCHAソルバー
2captcha / CapSolver等"] E -->|"ステルスモード"| H["人間らしい振る舞い
遅延・ヘッダーランダム化"] F --> I["チャレンジスクリプト実行
回答計算"] G --> I H --> I I --> J["セッションクッキー取得
cf_clearance等"] J --> K["実際のコンテンツ取得
リクエスト再送"] K --> L["レスポンス返却"]

内部的には、CloudflareのIUAMページからJavaScriptコードを抽出し、選択されたJSエンジン上で実行して回答を計算する。回答が正しければCloudflareからcf_clearanceクッキーが発行され、以降のリクエストでそのクッキーを使うことで保護をパスできる仕組みだ。

JavaScriptインタープリターの選択肢

インタープリター 特徴 推奨シナリオ
js2py(デフォルト) Python純正実装、外部依存なし 環境制限がある場合、シンプルな構成
Node.js 実際のV8エンジン使用、最高精度 複雑なチャレンジ対応が必要な場合
ChakraCore Microsoftのエンジン、高精度 Windows環境での安定性重視
V8(v8eval) Sonyの実装、高速 パフォーマンス重視の場合
Native Solver Python独自実装 軽量環境向け

インストールとセットアップ:基本から応用設定まで

インストール

pip install cloudscraper

依存パッケージ:

  • requests >= 2.31.0
  • js2py >= 0.74
  • pyOpenSSL
  • cffi

Node.jsを使う場合は追加インストールが必要:

# Node.jsのインストール(Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs

# macOS(Homebrew)
brew install node

基本的な使い方

requestsからの移行は1行の変更で完了する。

# Before: requests を使った従来のコード
import requests
response = requests.get("https://cloudflare-protected-site.com")
print(response.text)

# After: cloudscraperに変更(それ以外はほぼ同じ)
import cloudscraper
scraper = cloudscraper.create_scraper()
response = scraper.get("https://cloudflare-protected-site.com")
print(response.text)

POST、セッション管理、ヘッダー指定も従来通りに使える:

import cloudscraper

scraper = cloudscraper.create_scraper()

# POST リクエスト
response = scraper.post(
    "https://example.com/api",
    json={"key": "value"},
    headers={"Content-Type": "application/json"}
)

# セッションを維持したまま複数のページを取得
scraper.get("https://example.com/login")
scraper.post("https://example.com/login", data={"user": "xxx", "pass": "yyy"})
scraper.get("https://example.com/dashboard")

高度な設定:ステルスモードとプロキシローテーション

import cloudscraper

scraper = cloudscraper.create_scraper(
    interpreter='nodejs',          # Node.jsエンジンを使用
    browser={
        'browser': 'chrome',
        'platform': 'windows',
        'mobile': False
    },
    enable_stealth=True,           # ステルスモード有効化
    stealth_options={
        'min_delay': 2.0,          # 最小待機時間(秒)
        'max_delay': 6.0,          # 最大待機時間(秒)
        'human_like_delays': True, # 人間らしいランダム遅延
        'randomize_headers': True  # ヘッダーのランダム化
    },
    rotating_proxies=[             # プロキシローテーション
        'http://proxy1:8080',
        'http://proxy2:8080',
        'socks5://proxy3:1080'
    ],
    debug=True                     # デバッグログ有効
)

response = scraper.get("https://target-site.com")
レート制限とrobots.txtの遵守
cloudscraperを使ってCloudflare保護サイトにアクセスする際は、各サイトの利用規約とrobots.txtを必ず確認すること。過度なリクエストはIPブロックの原因となる。適切な待機時間(min_delay/max_delay)の設定と、robots.txtで許可された範囲内でのアクセスに留めることが必要だ。スクレイピングが利用規約で禁止されているサイトへの適用は避けること。

CAPTCHAソルバーとの連携

Turnstile CAPTCHAが必要な場合は、外部CAPTCHAサービスとの連携が可能だ:

import cloudscraper

scraper = cloudscraper.create_scraper(
    captcha={
        'provider': '2captcha',
        'api_key': 'YOUR_2CAPTCHA_API_KEY'
    }
)

# CapSolverを使う場合
scraper = cloudscraper.create_scraper(
    captcha={
        'provider': 'capsolver',
        'api_key': 'YOUR_CAPSOLVER_API_KEY'
    }
)

response = scraper.get("https://turnstile-protected-site.com")

対応CAPTCHAプロバイダー一覧:

  • 2captcha
  • anticaptcha
  • CapSolver
  • CapMonster Cloud
  • deathbycaptcha
  • 9kw
  • return_response(手動解決用)

実践的なユースケース:cloudscraperが活躍する4つのシナリオ

ユースケース1:価格監視・比較ツールの構築

ECサイトやオークションサイトの価格データを定期取得するシステムで、対象サイトがCloudflareで保護されている場合にcloudscraperが有効だ。

import cloudscraper
import time
import json
from datetime import datetime

scraper = cloudscraper.create_scraper(
    enable_stealth=True,
    stealth_options={'min_delay': 3.0, 'max_delay': 8.0}
)

def fetch_price(url: str) -> dict:
    """商品ページから価格情報を取得"""
    response = scraper.get(url)
    if response.status_code == 200:
        # ここでBeautifulSoupやlxml等でパース
        return {
            "timestamp": datetime.now().isoformat(),
            "url": url,
            "status": "ok",
            "html_length": len(response.text)
        }
    return {"status": "error", "code": response.status_code}

# 定期実行(実際のスケジューリングはcronや Apache Airflow を使う)
urls = ["https://example-shop.com/product/1", "https://example-shop.com/product/2"]
for url in urls:
    result = fetch_price(url)
    print(json.dumps(result, ensure_ascii=False))
    time.sleep(5)  # サーバー負荷を考慮した待機

ユースケース2:ニュース・コンテンツ集約システム

複数のメディアサイトからコンテンツを集約するシステムで、一部のサイトがCloudflare保護下にある場合の統一的なアクセスレイヤーとして使える。

import cloudscraper
from typing import Optional

class UnifiedScraper:
    """Cloudflare保護サイトと通常サイトを統一インターフェースでアクセス"""

    def __init__(self):
        self.scraper = cloudscraper.create_scraper(
            browser='chrome',
            enable_stealth=True
        )

    def fetch(self, url: str, timeout: int = 30) -> Optional[str]:
        try:
            response = self.scraper.get(url, timeout=timeout)
            response.raise_for_status()
            return response.text
        except Exception as e:
            print(f"Error fetching {url}: {e}")
            return None

scraper = UnifiedScraper()
html = scraper.fetch("https://cloudflare-news-site.com/articles")

ユースケース3:Cloudflareトークンの外部利用

他のHTTPクライアントやブラウザ自動化ツールで使うためのCloudflareトークンを取得する:

import cloudscraper

# Cloudflareトークンとユーザーエージェントを取得
tokens, user_agent = cloudscraper.get_tokens("https://target-site.com")
print(f"cf_clearance: {tokens.get('cf_clearance', 'N/A')}")
print(f"User-Agent: {user_agent}")

# クッキー文字列として取得(curl等での再利用向け)
cookie_string, user_agent = cloudscraper.get_cookie_string("https://target-site.com")
print(f"Cookie: {cookie_string}")
# 重要:取得したuser_agentを後続のリクエストでも必ず使用すること

ユースケース4:既存スクレイピングシステムへのプロキシ追加

すでにrequestsベースで動いているシステムへの最小限の変更でCFバイパスを追加する:

# 変更前のコード
# import requests
# session = requests.Session()

# 変更後:この2行を変えるだけ
import cloudscraper
session = cloudscraper.create_scraper()

# 以降のコードは変更不要
session.headers.update({"Accept-Language": "ja-JP,ja;q=0.9"})
response = session.get("https://cf-protected-site.com/data")
data = response.json()
cloudscraperの使いどころまとめ requests.getで403や503エラーが返ってくる Cloudflare 保護サイトへのアクセスが必要な場合、cloudscraperは最小限のコード変更で対応できる実用的な選択肢だ。完全なブラウザ自動化(Selenium/Playwright)と比べてリソース消費が少なく、サーバーサイドでの大量処理に向いている。ただし、Cloudflareの新しい検知手法への対応には常にタイムラグがあるため、ミッションクリティカルな用途には冗長化を検討すること。

cloudscraperで「突破できないCloudflare」と現実的な切り替え判断

cloudscraperはCloudflareのv1〜v3 JSチャレンジTurnstile CAPTCHAまではほぼ自動処理できる。一方で2026年に増えた以下の防御層は突破できないか、断続的に失敗する。

Cloudflare防御層 cloudscraperの対応 失敗時の症状 切替先候補
Bot Fight Mode(基本) ✅ ほぼ通る
Managed Challenge(v3) ⚠ アップデート直後数日NG 403連発 undetected-chromedriver
Turnstile(インタラクティブ) ❌ 不可 永久ループ Playwright + Stealth
Super Bot Fight Mode ❌ ほぼ不可 521 / 1015 rebrowser-playwright
商用WAF(Akamai等) ❌ 対象外 403 / 401 requests-html + 残留TLS指紋ライブラリ

経験則として、1日数百リクエスト規模の定期取得には cloudscraper が最も軽量だが、対象サイトがセッション維持型のSPAやTurnstileを導入していたら最初から Playwright + Stealth を選ぶ方が運用コストが下がる。cloudscraperはあくまで「requests のドロップイン置き換え」として、軽量・短時間ジョブで真価を発揮する。

# cloudscraperで失敗を検知して別ライブラリへフォールバックするテンプレ
import cloudscraper
from playwright.sync_api import sync_playwright

def fetch(url: str) -> str:
    scraper = cloudscraper.create_scraper(
        browser={"browser": "chrome", "platform": "darwin", "mobile": False}
    )
    r = scraper.get(url, timeout=20)
    if r.status_code in (403, 521, 1015) or "challenge-platform" in r.text:
        # 商用WAFやSuper Bot Fight Modeは Playwright で再試行
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=True)
            page = browser.new_page()
            page.goto(url, wait_until="networkidle")
            html = page.content()
            browser.close()
            return html
    return r.text

スクレイピングが「合法か」を判断する観点

cloudscraperの利用は技術的にはCloudflareの認証チャレンジを自動処理しているだけだが、対象サイトの利用規約・robots.txt・著作権 によって法的リスクが決まる。日本国内では2019年改正著作権法第30条の4により情報解析目的であれば学習データ収集は適法とされるが、商用転載目的だと2018年のRetty事件のような不正競争防止法上の論点が生じうる。コード自体ではなく取得後のデータ利用 に注意したい。

競合ツールとの比較:シナリオ別の選択基準

ツール 動作原理 リソース消費 精度 Cloudflare対応 用途
cloudscraper JSインタープリター内蔵 軽量 中〜高 v1/v2/v3/Turnstile 軽量スクレイピング
Selenium 実ブラウザ制御 重い 最高 完全対応 ブラウザ自動化全般
Playwright 実ブラウザ制御 重い 最高 完全対応 モダンブラウザ自動化
Browser Use AI+ブラウザ制御 最重 最高+AI判断 完全対応 AIエージェント連携
requests単体 HTTPクライアント 最軽量 低(CF非対応) 非対応 CF保護なしのサイト
Scrapy 非同期クローラー 中程度 低(CF非対応) 別途ミドルウェア要 大規模クロール

cloudscraperを選ぶべき状況

  • requests.getで直接アクセスできないCloudflare保護サイトが対象
  • 軽量・高速な処理が必要(GUIやブラウザプロセスを起動したくない)
  • 既存のrequestsベースコードを最小限の変更で対応させたい

Selenium/Playwrightを選ぶべき状況

  • JavaScript動的レンダリングが必要(SPAサイト等)
  • Cloudflare以外のbot保護(DataDome、Akamai等)も突破したい
  • クリック操作やフォーム入力など実際のインタラクションが必要

よくある質問

Q1:cloudscraper使用時にCloudflareChallengeErrorが発生する

Cloudflareが新しいチャレンジ形式を導入した直後に発生しやすい。まずcloudscraperを最新版にアップデートする(pip install --upgrade cloudscraper)。それでも解決しない場合は、インタープリターをjs2pyからnodejsに変更する(interpreter='nodejs')。Node.jsが未インストールの場合はnodejsをインストールしてから再試行する。

Q2:ステルスモードを有効にしても503エラーになる

ステルスモードのmin_delay/max_delayを増やしてみる(例:min_delay=5.0、max_delay=15.0)。また、プロキシを使用している場合は同一プロキシIPからのアクセス頻度が高すぎる可能性があるため、rotating_proxiesで複数のプロキシを指定してローテーションする。

Q3:日本語サイトでの文字化けへの対処

scraper = cloudscraper.create_scraper()
response = scraper.get("https://japanese-site.com")
response.encoding = 'utf-8'  # 明示的にエンコーディングを指定
print(response.text)

Q4:requests.Sessionと同じように使えるか

はい。create_scraper()が返すオブジェクトはrequests.Sessionのサブクラスであり、.cookies.headers.auth等すべてのSession属性が利用できる。

Q5:非同期処理(asyncio/aiohttp)との組み合わせは?

cloudscraperは同期APIのみ対応。非同期処理と組み合わせる場合はasyncio.get_event_loop().run_in_executor()でスレッドプールに委譲するか、非同期対応のCloudflareバイパスライブラリを検討する。


関連記事: AI自動化ツール完全ガイド2026|ノーコードからコードまで徹底比較

まとめと参照ソース

cloudscraperはrequestsライブラリへの最小限の変更でCloudflare保護サイトへのアクセスを自動化できる、実用性の高いOSSモジュールだ。v1/v2/v3チャレンジからTurnstile CAPTCHAまで幅広く対応しており、6,400スター超えのGitHub評価が示すように広く採用されている。

ただし、Cloudflareのアップデートへの対応が後追いになることがある点と、悪用防止のための利用規約遵守が求められる点は常に意識する必要がある。実際のプロダクション用途では、エラーハンドリングとリトライロジックの実装を適切に行った上で利用することを推奨する。

法的・倫理的注意事項
cloudscraperの使用にあたっては、対象サイトの利用規約・robots.txt・著作権を必ず確認すること。Cloudflare保護をバイパスすること自体が利用規約違反となるサイトも存在する。また、Computer Fraud and Abuse Act(米国)やその各国相当の法律に抵触しないよう、責任ある利用が求められる。

参照ソース