PHPでcaptcha解決:cURLを使った動作例(2026年)
captchaを解決するためにPHPで必要なのは、cURL拡張機能だけです。多くの環境にはすでに入っています。Scarnox APIにJSONのPOSTを1回送り、レスポンスからsolution.tokenを読み取り、そのトークンをサイトのフォームに送信します。このガイドでは、Scarnoxが現在プロキシなしで解決しているPopularCaptchaについて、PHPの流れ全体を説明します。
無料のトライアルクレジットで始める(カード登録は不要)と、他で使う前に、自分が管理しているページでスクリプトを試せます。
必要なもの
- PHP 8.0以降。
curlとjsonの拡張機能が有効になっていること。php -mで確認できます。 - ScarnoxのAPIキー。
- ページのPopularCaptchaウィジェットのサイトキー。見つけ方はcaptchaのサイトキーの見つけ方を参照してください。
ソルバー関数
この関数はAPIにPOSTし、errorIdを確認して、トークンを返します。失敗時は必ず例外を投げるので、呼び出し側がリトライするかどうかを決められます。
<?php
declare(strict_types=1);
const SCARNOX_API_KEY = 'scarnox_YOURAPIKEY';
const SCARNOX_API_URL = 'https://api.scarnox.com/api/tasks/create';
function solveCaptcha(string $sitekey, string $pageUrl, bool $invisible = false): string
{
$body = [
'captcha_type' => 'PopularCaptchaTaskProxyless',
'site_key' => $sitekey,
'site_url' => $pageUrl,
];
if ($invisible) {
$body['is_invisible'] = true;
}
$ch = curl_init(SCARNOX_API_URL);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($body, JSON_THROW_ON_ERROR),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . SCARNOX_API_KEY,
'Content-Type: application/json',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 185, // トークンの準備ができると戻る
]);
$raw = curl_exec($ch);
if ($raw === false) {
$error = curl_error($ch);
throw new RuntimeException('cURL error: ' . $error);
}
$data = json_decode((string) $raw, true);
if (!is_array($data)) {
throw new RuntimeException('Response was not JSON');
}
if (($data['errorId'] ?? 1) !== 0) {
throw new RuntimeException(
($data['errorCode'] ?? 'ERROR') . ': ' . ($data['errorDescription'] ?? 'unknown')
);
}
return (string) $data['solution']['token'];
}
AuthorizationヘッダーにはBearerの接頭辞を付けます。APIはトークンの準備ができるまでブロックし、ポーリングの手順はないので、タイムアウトは185秒です。
一時的な失敗をリトライする
失敗した解決には課金されないので、数回のリトライは安上がりです。呼び出しをループで囲み、失敗のたびに少し長く待ってください。
function solveWithRetry(string $sitekey, string $pageUrl, int $attempts = 3): string
{
$lastError = null;
for ($i = 1; $i <= $attempts; $i++) {
try {
return solveCaptcha($sitekey, $pageUrl);
} catch (RuntimeException $e) {
$lastError = $e;
fwrite(STDERR, "Attempt $i failed: " . $e->getMessage() . PHP_EOL);
sleep($i);
}
}
throw $lastError;
}
どの失敗で停止すべきかを含む完全なエラーのポリシーは、captcha解決のエラー処理を参照してください。
Cookieジャーを使ってトークンを送信する
多くのサイトは、captchaをフォームを読み込んだセッションに紐づけています。Cookieファイルを使うと、cURLはGETとPOSTで同じCookieを送れます。次の関数は、トークンをページのフォームに送信します。
function submitToken(string $pageUrl, string $token): string
{
$cookieFile = sys_get_temp_dir() . '/scarnox-cookies.txt';
// 先にGETして、サイトのセッションCookieを設定させる。
$ch = curl_init($pageUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIEFILE => $cookieFile,
CURLOPT_COOKIEJAR => $cookieFile,
CURLOPT_TIMEOUT => 60,
]);
curl_exec($ch);
// 次に、両方のcaptchaフィールドにトークンを入れてフォームをPOSTする。
$fields = http_build_query([
'email' => 'you@example.com',
'h-captcha-response' => $token,
'g-recaptcha-response' => $token,
]);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fields,
CURLOPT_TIMEOUT => 60,
]);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException('Form submit failed: ' . curl_error($ch));
}
return (string) $body;
}
重要な点は2つです。GETは解決の前に行われるので、Cookieが設定されています。そして、トークンは解決の直後に送信されます。トークンは約2分で期限切れになるからです。解決の呼び出しは、長いバッチの冒頭ではなく、この関数の直前に置いてください。
Cookieファイルはプロセス内のすべての呼び出しで共有されます。複数の会員登録を並行して行うなら、アカウントやセッションごとに別のファイルを使ってください。そうしないと、あるセッションが別のセッションのCookieを上書きしてしまい、2回目のPOSTが、captchaの問題に見える別の理由で失敗します。
まとめて組み立てる
$pageUrl = 'https://example.com/signup';
$token = solveWithRetry('YOUR-SITEKEY-UUID', $pageUrl);
$html = submitToken($pageUrl, $token);
echo strlen($html) . " bytes returned\n";
コマンドラインから実行します。
php signup.php
不可視のウィジェット
ウィジェットが不可視の場合は、solveCaptcha($sitekey, $pageUrl, true)を呼び出してください。リクエストにはis_invisibleフィールドが付きます。ページによっては、トークンを引数にJavaScriptのコールバックを呼ぶ必要があり、サーバー側のスクリプトはそれをトリガーできません。その場合は、ブラウザのツールを使ってください。パターンは不可視captchaのガイドで扱っています。
タイミングと期限切れ
トークンの有効期間は約2分です。解決と送信は近いタイミングに保ってください。期限切れのトークンと拒否されたトークンの見分け方は、captchaトークンの期限切れで説明しています。
スクレイピングの際の注意
PHPのスクリプトが公開ページをスクレイピングするなら、開始前にrobots.txtとサイトの利用規約を確認してください。リクエストの間には遅延を入れ、必要のない個人データは保持しないでください。captchaを解決しても、収集が許されている範囲が変わるわけではありません。法的な面はWebスクレイピングは合法かを参照してください。
料金
成功した解決ごとに料金がかかります。失敗した解決は課金されません。現在の料金は料金ページを参照してください。また、無料のトライアルクレジットで始める(カード登録は不要)ことができます。