
Sora Fujimoto
AI Solutions Architect
TLDR: このガイドでは、Botasaurus(Pythonで構築されたWebスクレイピングフレームワークで、検出回避機能を備えています)とCapSolver(CAPTCHAを自動的に解決するAPI)を組み合わせて、大規模なWebスクレイピング中にreCAPTCHA v2、reCAPTCHA v3、Cloudflare Turnstileを自動的に回避する方法を紹介します。コアプロセスは、環境のセットアップ、CapSolverブラウザ拡張機能を使用してCAPTCHAパラメータを特定、CapSolver APIをPythonのヘルパー関数を通じて呼び出して解決トークンを取得、最後にBotasaurusを使用してトークンをウェブページにインジェクトしてフォームを送信することです。

大規模なWebスクレイピングでは、自動アクセスをブロックするCAPTCHAに遭遇することがあります。このガイドでは、Botasaurus(強力なWebスクレイピングフレームワーク)とCapSolverを組み合わせて、reCAPTCHA v2、reCAPTCHA v3、Cloudflare TurnstileのCAPTCHAを自動的に解決する方法を紹介します。
Botasaurusは、検出回避機能を備えたPython用のWebスクレイピングフレームワークで、ブラウザの自動化を簡単にします。ブラウザタスク用のクリーンなデコレータベースのAPIを提供します。
主な特徴:
@browserベースのデコレータアプローチインストール:
pip install botasaurus
基本的な使い方:
from botasaurus.browser import browser, Driver
@browser()
def scrape_page(driver: Driver, data):
driver.get("https://example.com")
title = driver.get_text("h1")
return {"title": title}
# スクレイパーを実行
result = scrape_page()
CapSolverは、reCAPTCHAやCloudflare TurnstileなどのさまざまなCAPTCHAタイプを解決するAPIを提供するCAPTCHA解決サービスです。
サポートされているCAPTCHAタイプ:
APIキーの取得:
CAP-で始まる)pip install botasaurus capsolver requests python-dotenv
プロジェクトルートに.envファイルを作成します:
CAPSOLVER_API_KEY=CAP-YOUR_API_KEY_HERE
共有設定ローダーを作成します:
# shared/config.py
import os
from pathlib import Path
from dotenv import load_dotenv
# プロジェクトルートの.envファイルを読み込む
ROOT_DIR = Path(__file__).parent.parent
load_dotenv(ROOT_DIR / ".env")
class Config:
"""CapSolver統合の設定クラス。"""
# CapSolver APIキー
CAPSOLVER_API_KEY: str = os.getenv("CAPSOLVER_API_KEY", "")
# CapSolver APIエンドポイント
CAPSOLVER_API_URL = "https://api.capsolver.com"
CREATE_TASK_ENDPOINT = f"{CAPSOLVER_API_URL}/createTask"
GET_RESULT_ENDPOINT = f"{CAPSOLVER_API_URL}/getTaskResult"
@classmethod
def validate(cls) -> bool:
"""設定が有効か確認します。"""
if not cls.CAPSOLVER_API_KEY:
print("エラー: CAPSOLVER_API_KEYが設定されていません!")
return False
return True
APIと統合する前に、ターゲットのCAPTCHAに必要な正しいパラメータを特定する必要があります。CapSolver拡張機能は、すべての必要なパラメータを自動的に検出する簡単な方法を提供します。
Chrome Web StoreからCapSolver拡張機能をインストールしてください。
重要: CAPTCHAをトリガーする前にCapSolverパネルを閉じないでください。閉じると以前に検出された情報が削除されます。
拡張機能はすべての必要なreCAPTCHAパラメータを自動的に識別します:
検出器はAPI統合用にフォーマットされたJSON出力を提供し、解決タスクに必要な正確なパラメータをコピーしやすくなります。
詳細については、CAPTCHAパラメータの特定に関する完全ガイドを参照してください。
reCAPTCHA v2は、古典的な「I'm not a robot」チェックボックスCAPTCHAで、ユーザーに画像選択チャレンジを提示する場合があります。
CapSolver拡張機能の検出器(上記参照)または手動でサイトキーを検出できます:
ページのHTMLで以下を検索:
<div class="g-recaptcha" data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"></div>
またはJavaScriptで:
grecaptcha.render('container', {'sitekey': '6Le-xxxxx...'});
# utils/capsolver_helper.py
import time
import requests
from shared.config import Config
def solve_recaptcha_v2(
website_url: str,
website_key: str,
is_invisible: bool = False,
timeout: int = 120
) -> dict:
"""
CapSolver APIを使用してreCAPTCHA v2を解決します。
引数:
website_url: CAPTCHAが配置されているページのURL
website_key: reCAPTCHAサイトキー
is_invisible: 非表示reCAPTCHA v2かどうか
timeout: 解決を待つ最大時間(秒)
戻り値:
'gRecaptchaResponse'トークンを含むdict
"""
if not Config.validate():
raise Exception("設定が無効です - APIキーを確認してください")
# タスクペイロードを構築
task = {
"type": "ReCaptchaV2TaskProxyLess",
"websiteURL": website_url,
"websiteKey": website_key,
}
if is_invisible:
task["isInvisible"] = True
payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"task": task
}
# タスクを作成
response = requests.post(Config.CREATE_TASK_ENDPOINT, json=payload)
result = response.json()
if result.get("errorId") and result.get("errorId") != 0:
raise Exception(f"タスクの作成に失敗しました: {result.get('errorDescription')}")
task_id = result.get("taskId")
# 結果をポーリング
start_time = time.time()
while time.time() - start_time < timeout:
time.sleep(2)
result_payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"taskId": task_id
}
response = requests.post(Config.GET_RESULT_ENDPOINT, json=result_payload)
result = response.json()
if result.get("status") == "ready":
return result.get("solution", {})
elif result.get("status") == "failed":
raise Exception(f"タスクが失敗しました: {result.get('errorDescription')}")
raise Exception(f"{timeout}秒後にタイムアウトしました")
from botasaurus.browser import browser, Driver
from shared.config import Config
from utils.capsolver_helper import solve_recaptcha_v2
DEMO_URL = "https://www.google.com/recaptcha/api2/demo"
DEMO_SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
@browser(headless=False)
def solve_recaptcha_v2_with_api(driver: Driver, data: dict):
"""CapSolver APIを使用してreCAPTCHA v2を解決し、トークンをインジェクトします。"""
url = data.get("url", DEMO_URL)
site_key = data.get("site_key", DEMO_SITEKEY)
# ステップ1: ページを読み込む
driver.get(url)
driver.sleep(2)
# ステップ2: ページからサイトキーを抽出(オプション)
extracted_key = driver.run_js("""
const recaptchaDiv = document.querySelector('.g-recaptcha');
return recaptchaDiv ? recaptchaDiv.getAttribute('data-sitekey') : null;
""")
if extracted_key:
site_key = extracted_key
# ステップ3: CapSolver APIでCAPTCHAを解決
solution = solve_recaptcha_v2(
website_url=url,
website_key=site_key
)
token = solution.get("gRecaptchaResponse")
# ステップ4: トークンをページにインジェクト
driver.run_js(f"""
// 非表示テキストエリアの値を設定
const responseField = document.querySelector('[name="g-recaptcha-response"]');
if (responseField) {{
responseField.value = "{token}";
}}
// コールバックが利用可能な場合をトリガー
if (typeof ___grecaptcha_cfg !== 'undefined') {{
try {{
const clients = ___grecaptcha_cfg.clients;
for (const key in clients) {{
const client = clients[key];
if (client && client.callback) {{
client.callback("{token}");
}}
}}
}} catch (e) {{}}
}}
""")
# ステップ5: フォームを送信
submit_button = driver.select('input[type="submit"]')
if submit_button:
submit_button.click()
driver.sleep(2)
return {"success": True, "token_length": len(token)}
# デモを実行
result = solve_recaptcha_v2_with_api(data={"url": DEMO_URL, "site_key": DEMO_SITEKEY})
reCAPTCHA v3は非表示で、ユーザーの行動を分析して0.0から1.0までのスコアを生成します。
v2との主な違い: reCAPTCHA v3はpageActionパラメータを必要とします。
CapSolver拡張機能検出器を使用するのが最も簡単です。あるいは、ページのJavaScriptで以下を検索:
grecaptcha.execute('siteKey', {action: 'login'})
// 'login'がpageActionです
def solve_recaptcha_v3(
website_url: str,
website_key: str,
page_action: str,
timeout: int = 120
) -> dict:
"""
CapSolver APIを使用してreCAPTCHA v3を解決します。
引数:
website_url: CAPTCHAが配置されているページのURL
website_key: reCAPTCHAサイトキー
page_action: アクションパラメータ(v3用に必須)
timeout: 解決を待つ最大時間(秒)
戻り値:
'gRecaptchaResponse'トークンを含むdict
"""
if not Config.validate():
raise Exception("設定が無効です - APIキーを確認してください")
if not page_action:
raise Exception("reCAPTCHA v3にはpageActionが必須です")
# タスクペイロードを構築
task = {
"type": "ReCaptchaV3TaskProxyLess",
"websiteURL": website_url,
"websiteKey": website_key,
"pageAction": page_action, # v3用に必須
}
payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"task": task
}
# タスクを作成
response = requests.post(Config.CREATE_TASK_ENDPOINT, json=payload)
result = response.json()
if result.get("errorId") and result.get("errorId") != 0:
raise Exception(f"タスクの作成に失敗しました: {result.get('errorDescription')}")
task_id = result.get("taskId")
# 結果をポーリング
start_time = time.time()
while time.time() - start_time < timeout:
time.sleep(2)
result_payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"taskId": task_id
}
response = requests.post(Config.GET_RESULT_ENDPOINT, json=result_payload)
result = response.json()
if result.get("status") == "ready":
return result.get("solution", {})
elif result.get("status") == "failed":
raise Exception(f"タスクが失敗しました: {result.get('errorDescription')}")
raise Exception(f"{timeout}秒後にタイムアウトしました")
from botasaurus.browser import browser, Driver
from shared.config import Config
from utils.capsolver_helper import solve_recaptcha_v3
DEMO_URL = "https://recaptcha-demo.appspot.com/recaptcha-v3-request-scores.php"
DEMO_SITEKEY = "6LdyC2cUAAAAACGuDKpXeDorzUDWXmdqeg-xy696"
PAGE_ACTION = "examples/v3scores"
@browser(headless=False)
def solve_recaptcha_v3_with_api(driver: Driver, data: dict):
"""CapSolver APIを使用してreCAPTCHA v3を解決し、トークンをインジェクトします。"""
url = data.get("url", DEMO_URL)
site_key = data.get("site_key", DEMO_SITEKEY)
page_action = data.get("page_action", PAGE_ACTION)
# ステップ1: ページを読み込む
driver.get(url)
driver.sleep(2)
# ステップ2: CapSolver APIでCAPTCHAを解決
solution = solve_recaptcha_v3(
website_url=url,
website_key=site_key,
page_action=page_action
)
token = solution.get("gRecaptchaResponse")
# ステップ3: トークンをページにインジェクト
driver.run_js(f"""
const token = "{token}";
// 非表示フィールドが存在する場合を設定
const responseField = document.querySelector('[name="g-recaptcha-response"]');
if (responseField) {{
responseField.value = token;
}}
// フォームが存在するがフィールドがない場合に非表示フィールドを作成
const forms = document.querySelectorAll('form');
forms.forEach(form => {{
let field = form.querySelector('[name="g-recaptcha-response"]');
if (!field) {{
field = document.createElement('input');
field.type = 'hidden';
field.name = 'g-recaptcha-response';
form.appendChild(field);
}}
field.value = token;
}});
""")
# ステップ4: 送信または検証
buttons = driver.select_all("button")
for button in buttons:
if "verify" in button.text.lower() or "submit" in button.text.lower():
button.click()
driver.sleep(2)
break
return {"success": True, "token_length": len(token)}
# デモを実行
result = solve_recaptcha_v3_with_api(data={
"url": DEMO_URL,
"site_key": DEMO_SITEKEY,
"page_action": PAGE_ACTION
})
Cloudflare Turnstileは、従来のCAPTCHAよりも侵入性が少ないプライバシー重視のCAPTCHAの代替です。
reCAPTCHAとの主な違い:
AntiTurnstileTaskProxyLesstoken(gRecaptchaResponseではない)0x4で始まりますページのHTMLで以下を検索:
<div class="cf-turnstile" data-sitekey="0x4AAAAAAABS7vwvV6VFfMcD"></div>
def solve_turnstile(
website_url: str,
website_key: str,
action: str = None,
cdata: str = None,
timeout: int = 120
) -> dict:
"""
CapSolver APIを使用してCloudflare Turnstileを解決する。
引数:
website_url: Turnstileが配置されているページのURL
website_key: Turnstileサイトキー(0x4で始まる)
action: data-action属性から取得されたオプショナルなアクション
cdata: data-cdata属性から取得されたオプショナルなcdata
timeout: 解決を待つ最大時間(秒)
戻り値:
「token」フィールドを持つ辞書
"""
if not Config.validate():
raise Exception("無効な設定 - APIキーの確認が必要です")
# タスクペイロードを構築
task = {
"type": "AntiTurnstileTaskProxyLess",
"websiteURL": website_url,
"websiteKey": website_key,
}
# オプショナルなメタデータを追加
metadata = {}
if action:
metadata["action"] = action
if cdata:
metadata["cdata"] = cdata
if metadata:
task["metadata"] = metadata
payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"task": task
}
# タスクを作成
response = requests.post(Config.CREATE_TASK_ENDPOINT, json=payload)
result = response.json()
if result.get("errorId") and result.get("errorId") != 0:
raise Exception(f"タスクの作成に失敗しました: {result.get('errorDescription')}")
task_id = result.get("taskId")
# 結果をポーリング
start_time = time.time()
while time.time() - start_time < timeout:
time.sleep(2)
result_payload = {
"clientKey": Config.CAPSOLVER_API_KEY,
"taskId": task_id
}
response = requests.post(Config.GET_RESULT_ENDPOINT, json=result_payload)
result = response.json()
if result.get("status") == "ready":
return result.get("solution", {})
elif result.get("status") == "failed":
raise Exception(f"タスクが失敗しました: {result.get('errorDescription')}")
raise Exception(f"{timeout}秒後にタイムアウトしました")
from botasaurus.browser import browser, Driver
from shared.config import Config
from utils.capsolver_helper import solve_turnstile
DEMO_URL = "https://peet.ws/turnstile-test/non-interactive.html"
DEMO_SITEKEY = "0x4AAAAAAABS7vwvV6VFfMcD"
@browser(headless=False)
def solve_turnstile_with_api(driver: Driver, data: dict):
"""CapSolver APIを使用してCloudflare Turnstileを解決し、トークンを挿入します。"""
url = data.get("url", DEMO_URL)
site_key = data.get("site_key", DEMO_SITEKEY)
# ステップ1: ページを読み込む
driver.get(url)
driver.sleep(3)
# ステップ2: ページからサイトキーを抽出(オプショナル)
extracted_params = driver.run_js("""
const turnstileDiv = document.querySelector('.cf-turnstile, [data-sitekey]');
if (turnstileDiv) {
const key = turnstileDiv.getAttribute('data-sitekey');
if (key && key.startsWith('0x')) {
return {
sitekey: key,
action: turnstileDiv.getAttribute('data-action')
};
}
}
return null;
""")
if extracted_params and extracted_params.get("sitekey"):
site_key = extracted_params["sitekey"]
# ステップ3: CapSolver APIでTurnstileを解決
solution = solve_turnstile(
website_url=url,
website_key=site_key,
action=extracted_params.get("action") if extracted_params else None
)
token = solution.get("token")
# ステップ4: トークンをページに挿入
driver.run_js(f"""
const token = "{token}";
// cf-turnstile-responseフィールドを検索して入力
const responseFields = [
document.querySelector('[name="cf-turnstile-response"]'),
document.querySelector('[name="cf_turnstile_response"]'),
document.querySelector('input[name*="turnstile"]')
];
for (const field of responseFields) {{
if (field) {{
field.value = token;
break;
}}
}}
// フォームが存在するがフィールドがない場合、隠しフィールドを作成
const forms = document.querySelectorAll('form');
forms.forEach(form => {{
let field = form.querySelector('[name="cf-turnstile-response"]');
if (!field) {{
field = document.createElement('input');
field.type = 'hidden';
field.name = 'cf-turnstile-response';
form.appendChild(field);
}}
field.value = token;
}});
""")
# ステップ5: フォームを送信
submit_btn = driver.select('button[type="submit"], input[type="submit"]')
if submit_btn:
submit_btn.click()
driver.sleep(2)
return {"success": True, "token_length": len(token)}
# デモを実行
result = solve_turnstile_with_api(data={"url": DEMO_URL, "site_key": DEMO_SITEKEY})
| Captchaタイプ | タスクタイプ | 応答フィールド | 必須パラメータ |
|---|---|---|---|
| reCAPTCHA v2 | ReCaptchaV2TaskProxyLess |
gRecaptchaResponse |
websiteURL, websiteKey |
| reCAPTCHA v2エンタープライズ | ReCaptchaV2EnterpriseTaskProxyLess |
gRecaptchaResponse |
websiteURL, websiteKey |
| reCAPTCHA v3 | ReCaptchaV3TaskProxyLess |
gRecaptchaResponse |
websiteURL, websiteKey, pageAction |
| reCAPTCHA v3エンタープライズ | ReCaptchaV3EnterpriseTaskProxyLess |
gRecaptchaResponse |
websiteURL, websiteKey, pageAction |
| Cloudflare Turnstile | AntiTurnstileTaskProxyLess |
token |
websiteURL, websiteKey |
データセンターアドレスをブロックするサイトの場合、プロキシバージョン(例: ReCaptchaV2Task)を使用し、独自の住宅プロキシを提供してください。
1. トークンの有効期限
Captchaトークンはすぐに期限切れになります(通常2分以内)。取得した後すぐにトークンを使用してください:
# トークンを取得
solution = solve_recaptcha_v2(url, site_key)
token = solution.get("gRecaptchaResponse")
# 後で使用しないで、すぐに使用してください
driver.run_js(f'document.querySelector("[name=g-recaptcha-response]").value = "{token}"')
driver.select('button[type="submit"]').click()
2. エラー処理
APIの失敗に対して適切なエラー処理を実装してください:
try:
solution = solve_recaptcha_v2(url, site_key)
except Exception as e:
print(f"Captchaの解決に失敗しました: {e}")
# リトライロジックやフォールバックを実装してください
3. レートリミット
リクエスト間の遅延を追加して、アンチボット対策をトリガーしないようにしてください:
driver.sleep(2) # ページ読み込み後に待機
# ... Captchaを解決 ...
driver.sleep(1) # フォーム送信前に待機
4. 設定の検証
リクエストを行う前にAPIキーの検証を常に実施してください:
if not Config.validate():
raise Exception("APIキーの設定を確認してください(.envファイルに配置)")
BotasaurusをCapSolverと組み合わせることで、ウェブスクレイピングプロジェクトでCaptchaを処理する強力なソリューションが提供されます。APIベースのアプローチにより、解決プロセスを完全に制御でき、さまざまなCaptchaタイプで信頼性のある動作が可能です。
即座に自動化予算を増やす!
CapSolverアカウントにチャージする際にボーナスコード CAPN を使用すると、毎回 5%のボーナス を受け取れます — 制限なし。
今すぐCapSolverダッシュボードで交換してください
websiteURLとwebsiteKeyパラメータが必要ですpageActionパラメータが必要ですgRecaptchaResponseではなくtokenフィールドを返します最も効果的な方法は、検出防止機能を備えた強力なブラウザ自動化フレームワーク(例: Botasaurus)を使用し、Captcha解決用の専用API(例: CapSolver)と統合することです。
Botasaurusは、シンプルなデコレータベースのAPIを提供し、ターゲットサイトから検出されたりブロックされたりするリスクを最小限に抑えるために必要な組み込みのステルス機能を備えています。
両方ともwebsiteURLとwebsiteKeyパラメータが必要ですが、reCAPTCHA v3(非表示のスコアベースバージョン)はタスクペイロードにpageActionパラメータを追加する必要があります。
トークン(例: gRecaptchaResponseまたはtoken)を取得した後、サーバーにフォームを成功裏に送信するには、まずトークンをターゲットページの隠しフォームフィールドにJavaScript実行コマンドで挿入する必要があります。
CapSolverが提供するreCAPTCHAとTurnstileの解決トークンは非常に短期間で有効期限が切れるため、通常は約2分以内に使用する必要があります。
スケーラブルなRustウェブスクレイピングアーキテクチャを学びましょう。リクエスト、スクレイパー、非同期スクレイピング、ヘッドレスブラウザスクレイピング、プロキシローテーション、およびコンプライアンス対応のCAPTCHA処理で。

2026年のデータ・アズ・ア・サービス(DaaS)を理解する。その利点、ユースケース、およびリアルタイムの洞察と拡張性を通じて企業を変革する方法について探る。
