
Sora Fujimoto
AI Solutions Architect

ウェブスクレイピングは、データ収集、市場調査、競合分析において不可欠なツールとなっています。しかし、スクレイピング技術が進化するにつれて、ウェブサイトがデータを保護するために使用する防御も進化しています。スクレイパーが直面する最も一般的な障壁はキャプチャです。これは、人間とボットを区別するように設計された面倒なチャレンジです。
一度でも「人間であることを確認してください」というメッセージに遭遇したことがあるなら、その煩わしさを知っているでしょう。幸いなことに、強力な組み合わせがあります:Scraplingによる知的なウェブスクレイピングと、CapSolverによる自動キャプチャ解決です。
このガイドでは、これらのツールを統合してキャプチャ保護サイトを成功裏にスクレイピングするためのすべての手順を紹介します。GoogleのReCaptcha v2、非表示のReCaptcha v3、CloudflareのTurnstileに対応しています。
Scraplingは、"サイトの変更から学び、それに合わせて進化する最初の適応型スクレイピングライブラリ"と自己紹介する現代的なPythonウェブスクレイピングライブラリです。データ抽出を簡単にし、強力なアンチボット機能を提供しています。
基本的なパーサー機能をインストールするには:
pip install scrapling
ブラウザ自動化を含むすべての機能をインストールするには:
pip install "scrapling[fetchers]"
scrapling install
AI機能を含むすべての機能をインストールするには:
pip install "scrapling[all]"
scrapling install
Scraplingはクラスメソッドを使用してHTTPリクエストを行います:
from scrapling import Fetcher
# GETリクエスト
response = Fetcher.get("https://example.com")
# データを伴うPOSTリクエスト
response = Fetcher.post("https://example.com/api", data={"key": "value"})
# レスポンスにアクセス
print(response.status) # HTTPステータスコード
print(response.body) # ラウバイト
print(response.body.decode()) # デコードされたテキスト
CapSolverは、さまざまなタイプのキャプチャを自動的に解決するためのキャプチャソルビングサービスです。高度なAIを用いて、あらゆるプログラミング言語やスクレイピングフレームワークとシームレスに統合するシンプルなAPIを提供します。
自動化予算を即座に増やす!
CapSolverアカウントにチャージする際、ボーナスコードSCRAPLINGを使用すると、毎回チャージに6%のボーナスが追加されます — Scrapling統合ユーザー向け特別コードです。
今すぐCapSolverダッシュボードで利用してください。
CapSolverは2つの主要なエンドポイントを使用します:
POST https://api.capsolver.com/createTaskPOST https://api.capsolver.com/getTaskResult特定のキャプチャタイプに進む前に、CapSolver APIワークフローを処理する再利用可能なヘルパ関数を作成しましょう:
import requests
import time
CAPSOLVER_API_KEY = "YOUR_API_KEY"
def solve_captcha(task_type, website_url, website_key, **kwargs):
"""
CapSolver APIを使用した汎用的なキャプチャソルバー。
引数:
task_type: キャプチャタスクのタイプ(例: "ReCaptchaV2TaskProxyLess")
website_url: キャプチャが表示されているページのURL
website_key: キャプチャのサイトキー
**kwargs: キャプチャタイプに特有の追加パラメータ
戻り値:
dict: トークンとその他のデータを含む解決結果
"""
payload = {
"clientKey": CAPSOLVER_API_KEY,
"task": {
"type": task_type,
"websiteURL": website_url,
"websiteKey": website_key,
**kwargs
}
}
# タスクの作成
response = requests.post(
"https://api.capsolver.com/createTask",
json=payload
)
result = response.json()
if result.get("errorId") != 0:
raise Exception(f"タスク作成に失敗しました: {result.get('errorDescription')}")
task_id = result.get("taskId")
print(f"タスク作成: {task_id}")
# 結果のポーリング
max_attempts = 60 # 最大2分間のポーリング
for attempt in range(max_attempts):
time.sleep(2)
response = requests.post(
"https://api.capsolver.com/getTaskResult",
json={
"clientKey": CAPSOLVER_API_KEY,
"taskId": task_id
}
)
result = response.json()
if result.get("status") == "ready":
print(f"キャプチャが{(attempt + 1) * 2}秒で解決されました")
return result.get("solution")
if result.get("errorId") != 0:
raise Exception(f"エラー: {result.get('errorDescription')}")
print(f"待機中...(試行回数 {attempt + 1})")
raise Exception("タイムアウト: キャプチャの解決に時間がかかりすぎました")
この関数は、タスクの作成、結果のポーリング、解決結果の返却をすべて処理します。このガイドの残りの部分でもこの関数を使用します。
ReCaptcha v2は、古典的な「私はロボットではありません」チェックボックスキャプチャです。トリガーされると、ユーザーに画像内のオブジェクトを識別するよう求められます(信号機、歩道の横断歩道など)。スクレイパーにとっては、これをプログラム的に解決する必要があります。
サイトキーは通常、ページHTMLにあります:
<div class="g-recaptcha" data-sitekey="6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABCD"></div>
またはスクリプトタグ内にあります:
<script src="https://www.google.com/recaptcha/api.js?render=6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABCD"></script>
from scrapling import Fetcher
def scrape_with_recaptcha_v2(target_url, site_key, form_url=None):
"""
ReCaptcha v2で保護されたページをスクレイピングします。
引数:
target_url: キャプチャが表示されているURL
site_key: ReCaptchaのサイトキー
form_url: フォームを送信するURL(デフォルトはtarget_url)
戻り値:
キャプチャで保護されたページからのレスポンス
"""
# CapSolverを使用してキャプチャを解決
print("ReCaptcha v2を解決中...")
solution = solve_captcha(
task_type="ReCaptchaV2TaskProxyLess",
website_url=target_url,
website_key=site_key
)
captcha_token = solution["gRecaptchaResponse"]
print(f"トークンを取得: {captcha_token[:50]}...")
# Scraplingのクラスメソッドを使用してキャプチャトークンでフォームを送信
submit_url = form_url or target_url
response = Fetcher.post(
submit_url,
data={
"g-recaptcha-response": captcha_token,
# ウェブサイトが要求する他のフォームフィールドを追加してください
}
)
return response
# 使用例
if __name__ == "__main__":
url = "https://example.com/protected-page"
site_key = "6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABCD"
result = scrape_with_recaptcha_v2(url, site_key)
print(f"ステータス: {result.status}")
print(f"コンテンツ長: {len(result.body)}") # バイトデータを取得するには .body を使用してください
非表示ReCaptcha v2(チェックボックスがなく、フォーム送信時にトリガーされる)には、isInvisibleパラメータを追加してください:
solution = solve_captcha(
task_type="ReCaptchaV2TaskProxyLess",
website_url=target_url,
website_key=site_key,
isInvisible=True
)
ReCaptcha v2企業版の場合、別のタスクタイプを使用してください:
solution = solve_captcha(
task_type="ReCaptchaV2EnterpriseTaskProxyLess",
website_url=target_url,
website_key=site_key,
enterprisePayload={
"s": "必要に応じてペイロードのs値を指定"
}
)
ReCaptcha v3はv2とは異なり、背景で非表示で動作し、ユーザーの行動に基づいてスコア(0.0〜1.0)を割り当てます。スコアが1.0に近いほど、人間の活動である可能性が高くなります。
| 面 | ReCaptcha v2 | ReCaptcha v3 |
|---|---|---|
| ユーザー操作 | チェックボックス/画像チャレンジ | なし(非表示) |
| 出力 | 通過/失敗 | スコア(0.0〜1.0) |
| アクションパラメータ | 必要なし | 必須 |
| 使用タイミング | フォーム、ログイン | すべてのページロード |
アクションパラメータはウェブサイトのJavaScriptに指定されています:
grecaptcha.execute('6LcxxxxxxxxxxxxxxxxABCD', {action: 'submit'})
一般的なアクションには、submit、login、register、homepage、contactなどがあります。
from scrapling import Fetcher
def scrape_with_recaptcha_v3(target_url, site_key, page_action="submit", min_score=0.7):
"""
ReCaptcha v3で保護されたページをスクレイピングします。
引数:
target_url: キャプチャが表示されているURL
site_key: ReCaptchaのサイトキー
page_action: アクションパラメータ(grecaptcha.executeで見つかる)
min_score: 要求する最小スコア(0.1〜0.9)
戻り値:
キャプチャで保護されたページからのレスポンス
"""
print(f"ReCaptcha v3を解決中(アクション: {page_action})...")
solution = solve_captcha(
task_type="ReCaptchaV3TaskProxyLess",
website_url=target_url,
website_key=site_key,
pageAction=page_action
)
captcha_token = solution["gRecaptchaResponse"]
print(f"スコア付きトークンを取得: {solution.get('score', 'N/A')}")
# Scraplingのクラスメソッドを使用してトークンでリクエストを送信
response = Fetcher.post(
target_url,
data={
"g-recaptcha-response": captcha_token,
},
headers={
"User-Agent": solution.get("userAgent", "Mozilla/5.0")
}
)
return response
# 使用例
if __name__ == "__main__":
url = "https://example.com/api/data"
site_key = "6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABCD"
result = scrape_with_recaptcha_v3(url, site_key, page_action="getData")
print(f"レスポンス: {result.body.decode()[:200]}") # コンテンツを取得するには .body を使用してください
solution = solve_captcha(
task_type="ReCaptchaV3EnterpriseTaskProxyLess",
website_url=target_url,
website_key=site_key,
pageAction=page_action,
enterprisePayload={
"s": "オプションのsパラメータ"
}
)
Cloudflare Turnstileは、従来のキャプチャの「ユーザーに優しく、プライバシーを保護する」代替として設計された新しいキャプチャです。Cloudflareを使用しているウェブサイトでますます一般的になっています。
Turnstileは3つのモードがあります:
幸いなことに、CapSolverはすべてのモードを自動的に処理します。
ページHTMLにTurnstileが表示されているのを確認してください:
<div class="cf-turnstile" data-sitekey="0x4xxxxxxxxxxxxxxxxxxxxxxxxxx"></div>
またはJavaScript内:
turnstile.render('#container', {
sitekey: '0x4xxxxxxxxxxxxxxxxxxxxxxxxxx',
callback: function(token) { ... }
});
from scrapling import Fetcher
def scrape_with_turnstile(target_url, site_key, action=None, cdata=None):
"""
Cloudflare Turnstileで保護されたページをスクレイピングします。
引数:
target_url: キャプチャが表示されているURL
site_key: Turnstileのサイトキー(0x4...で始まる)
action: オプションのアクションパラメータ
cdata: オプションのcdataパラメータ
戻り値:
キャプチャで保護されたページからのレスポンス
"""
print("Cloudflare Turnstileを解決中...")
# 提供されたメタデータを構築
metadata = {}
if action:
metadata["action"] = action
if cdata:
metadata["cdata"] = cdata
task_params = {
"task_type": "AntiTurnstileTaskProxyLess",
"website_url": target_url,
"website_key": site_key,
}
if metadata:
task_params["metadata"] = metadata
solution = solve_captcha(**task_params)
turnstile_token = solution["token"]
user_agent = solution.get("userAgent", "")
print(f"Turnstileトークンを取得: {turnstile_token[:50]}...")
# ヘッダーを設定
headers = {}
if user_agent:
headers["User-Agent"] = user_agent
# トークンを使用して送信
response = Fetcher.post(
target_url,
data={
"cf-turnstile-response": turnstile_token,
},
headers=headers
)
return response
# 使用例
if __name__ == "__main__":
url = "https://example.com/protected-page"
site_key = "0x4xxxxxxxxxxxxxxxxxxxxxxxxxx"
result = scrape_with_turnstile(url, site_key)
print(f"ステータス: {result.status}")
print(f"コンテンツ長: {len(result.body)}") # バイトデータを取得するには .body を使用してください
headers=headers
)
return response
if name == "main":
url = "https://example.com/protected"
site_key = "0x4AAAAAAAxxxxxxxxxxxxxx"
result = scrape_with_turnstile(url, site_key)
print(f"成功!{len(result.body)}バイト取得しました") # コンテンツには.bodyを使用してください
一部の実装では追加のパラメータが必要な場合があります:
solution = solve_captcha(
task_type="AntiTurnstileTaskProxyLess",
website_url=target_url,
website_key=site_key,
metadata={
"action": "login",
"cdata": "session_id_or_custom_data"
}
)
単純なHTTPリクエストでは不十分な場合があります。サイトは以下をチェックする高度なボット検出技術を使用している可能性があります:
ScraplingのStealthyFetcherは、実際のブラウザエンジンを使用し、スティールトの修正によりブラウザレベルのアンチ検出を提供します。
StealthyFetcherは以下を備えた修正されたFirefoxブラウザを使用します:
| シナリオ | Fetcherを使用する | StealthyFetcherを使用する |
|---|---|---|
| 簡単なフォームとキャプチャ | はい | いいえ |
| 多くのJavaScriptページ | いいえ | はい |
| 複数のアンチボットレイヤー | いいえ | はい |
| スピードが重要 | はい | いいえ |
| Cloudflare Under Attackモード | いいえ | はい |
最大限の効果を得るために両方を併用する方法は以下の通りです:
from scrapling import StealthyFetcher
import asyncio
async def scrape_with_stealth_and_recaptcha(target_url, site_key, captcha_type="v2"):
"""
StealthyFetcherのアンチボット機能とCapSolverを組み合わせて、ReCaptchaを解決します。
Args:
target_url: スクレイピングするURL
site_key: キャプチャサイトキー
captcha_type: "v2" または "v3"
Returns:
キャプチャを解決した後のページのコンテンツ
"""
# まず、CapSolverを使用してキャプチャを解決します
print(f"ReCaptcha {captcha_type}を解決中...")
if captcha_type == "v2":
solution = solve_captcha(
task_type="ReCaptchaV2TaskProxyLess",
website_url=target_url,
website_key=site_key
)
token = solution["gRecaptchaResponse"]
elif captcha_type == "v3":
solution = solve_captcha(
task_type="ReCaptchaV3TaskProxyLess",
website_url=target_url,
website_key=site_key,
pageAction="submit"
)
token = solution["gRecaptchaResponse"]
else:
raise ValueError(f"不明なキャプチャタイプ: {captcha_type}")
print(f"トークンを取得しました: {token[:50]}...")
# StealthyFetcherを使用してブラウザのような挙動をします
fetcher = StealthyFetcher()
# ページに移動します
page = await fetcher.async_fetch(target_url)
# JavaScriptを使用してReCaptchaの解決をインジェクトします
await page.page.evaluate(f'''() => {{
// g-recaptcha-responseフィールドを見つけて値を設定します
let field = document.querySelector('textarea[name="g-recaptcha-response"]');
if (!field) {{
field = document.createElement('textarea');
field.name = "g-recaptcha-response";
field.style.display = "none";
document.body.appendChild(field);
}}
field.value = "{token}";
}}''')
# 送信ボタンを見つけてクリックします
submit_button = page.css('button[type="submit"], input[type="submit"]')
if submit_button:
await submit_button[0].click()
# ナビゲーションを待機します
await page.page.wait_for_load_state('networkidle')
# 最終的なページコンテンツを取得します
content = await page.page.content()
return content
# シンクロナスなラッパーで使いやすくします
def scrape_stealth(target_url, site_key, captcha_type="v2"):
"""非同期のアンチスティールトスカッパーのシンクロナスなラッパー。"""
return asyncio.run(
scrape_with_stealth_and_recaptcha(target_url, site_key, captcha_type)
)
# 例の使用方法
if __name__ == "__main__":
url = "https://example.com/highly-protected-page"
site_key = "6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABCD"
content = scrape_stealth(url, site_key, captcha_type="v2")
print(f"{len(content)}バイトのコンテンツを取得しました")
from scrapling import StealthyFetcher
import asyncio
class StealthScraper:
"""複数のページ間でセッションを維持するスクレイパー。"""
def __init__(self, api_key):
self.api_key = api_key
self.fetcher = None
async def __aenter__(self):
self.fetcher = StealthyFetcher()
return self
async def __aexit__(self, *args):
if self.fetcher:
await self.fetcher.close()
async def solve_and_access(self, url, site_key, captcha_type="v2"):
"""ReCaptchaを解決し、ページにアクセスします。"""
global CAPSOLVER_API_KEY
CAPSOLVER_API_KEY = self.api_key
# ReCaptchaを解決します
task_type = f"ReCaptcha{captcha_type.upper()}TaskProxyLess"
solution = solve_captcha(
task_type=task_type,
website_url=url,
website_key=site_key
)
token = solution["gRecaptchaResponse"]
# ページに移動し、トークンをインジェクトします
page = await self.fetcher.async_fetch(url)
# ... 以降のページ操作を続けます
return page
# 使用方法
async def main():
async with StealthScraper("your_api_key") as scraper:
page1 = await scraper.solve_and_access(
"https://example.com/login",
"site_key_here",
"v2"
)
# 以降のリクエストでセッションが維持されます
page2 = await scraper.solve_and_access(
"https://example.com/dashboard",
"another_site_key",
"v3"
)
asyncio.run(main())
サイトに過度のリクエストを送らないでください。リクエスト間に遅延を実装します:
import time
import random
def polite_scrape(urls, min_delay=2, max_delay=5):
"""人間のように見えるようにランダムな遅延を用いてスクレイピングします。"""
results = []
for url in urls:
result = scrape_page(url)
results.append(result)
# リクエスト間のランダムな遅延
delay = random.uniform(min_delay, max_delay)
time.sleep(delay)
return results
常に失敗を丁寧に処理してください:
def robust_solve_captcha(task_type, website_url, website_key, max_retries=3, **kwargs):
"""自動リトライを用いたキャプチャの解決。"""
for attempt in range(max_retries):
try:
return solve_captcha(task_type, website_url, website_key, **kwargs)
except Exception as e:
print(f"試行 {attempt + 1} に失敗: {e}")
if attempt < max_retries - 1:
time.sleep(5) # リトライ前に待機
else:
raise
スクレイピングする前に、ウェブサイトのrobots.txtを確認してください:
from urllib.robotparser import RobotFileParser
def can_scrape(url):
"""robots.txtによってスクレイピングが許可されているか確認します。"""
rp = RobotFileParser()
rp.set_url(f"{url}/robots.txt")
rp.read()
return rp.can_fetch("*", url)
スケールを拡大する際は、IPブロックを避けるためにプロキシをローテーションしてください:
# CapSolverはプロキシ対応のタスクをサポートしています
solution = solve_captcha(
task_type="ReCaptchaV2Task", # 注意: "ProxyLess"はなし
website_url=target_url,
website_key=site_key,
proxy="http://user:pass@proxy.example.com:8080"
)
キャプチャトークンは通常1〜2分で有効期限が切れます。複数のリクエストが必要な場合、トークンを再利用してください:
import time
class CaptchaCache:
def __init__(self, ttl=120): # 2分のデフォルトTTL
self.cache = {}
self.ttl = ttl
def get_or_solve(self, key, solve_func):
"""キャッシュされたトークンを取得または解決します。"""
if key in self.cache:
token, timestamp = self.cache[key]
if time.time() - timestamp < self.ttl:
return token
token = solve_func()
self.cache[key] = (token, time.time())
return token
| 特徴 | ReCaptcha v2 | ReCaptcha v3 | Cloudflare Turnstile |
|---|---|---|---|
| ユーザーの操作 | チェックボックス + 必要に応じてチャレンジ | なし | 最小限またはなし |
| サイトキーの形式 | 6L... |
6L... |
0x4... |
| 応答フィールド | g-recaptcha-response |
g-recaptcha-response |
cf-turnstile-response |
| アクションパラメータ | なし | 必須 | オプション |
| 解決時間 | 1〜10秒 | 1〜10秒 | 1〜20秒 |
| CapSolverタスク | ReCaptchaV2TaskProxyLess |
ReCaptchaV3TaskProxyLess |
AntiTurnstileTaskProxyLess |
| 特徴 | Fetcher | StealthyFetcher |
|---|---|---|
| 速度 | 非常に速い | 遅い |
| JavaScriptサポート | なし | あり |
| ブラウザフィンガープリント | なし | 実際のFirefox |
| メモリ使用量 | 低い | 高い |
| Cloudflare回避 | なし | あり |
| 最適な用途 | 簡単なリクエスト | 複雑なアンチボット |
CapSolverの料金ページを確認してください。
ページソース(Ctrl+U)で以下を検索してください:
data-sitekey属性grecaptcha.executeのJavaScriptコールrender=パラメータclass="cf-turnstile"のTurnstileトークンは通常1〜2分で期限切れになります。フォーム送信に近いタイミングでキャプチャを解決してください。検証エラーが発生した場合は、新しいトークンで再解決してください。
はい!解決関数を非同期エグゼキュータでラップします:
import asyncio
async def async_solve_captcha(*args, **kwargs):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(
None,
lambda: solve_captcha(*args, **kwargs)
)
それぞれのキャプチャを個別に解決し、すべてのトークンを送信に含めます:
# 複数のReCaptchasを解決します
solution_v2 = solve_captcha("ReCaptchaV2TaskProxyLess", url, key1)
solution_v3 = solve_captcha("ReCaptchaV3TaskProxyLess", url, key2, pageAction="submit")
# Scraplingクラスのメソッドを使用してトークンを送信します
response = Fetcher.post(url, data={
"g-recaptcha-response": solution_v2["gRecaptchaResponse"],
"g-recaptcha-response-v3": solution_v3["gRecaptchaResponse"],
})
ScraplingとCapSolverを組み合わせることで、キャプチャ保護付きのウェブサイトをスクレイピングするための強力なソリューションが提供されます。以下に要約します:
責任を持ってスクレイピングしてください:
スクレイピングを開始する準備ができましたか?CapSolverのAPIキーをcapsolver.comで取得し、pip install "scrapling[all]"でScraplingをインストールしてください。
スケーラブルなRustウェブスクレイピングアーキテクチャを学びましょう。リクエスト、スクレイパー、非同期スクレイピング、ヘッドレスブラウザスクレイピング、プロキシローテーション、およびコンプライアンス対応のCAPTCHA処理で。

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