Solver captcha di PHP dengan cURL: contoh kerja (2026)
PHP hanya membutuhkan ekstensi cURL, yang sudah tersedia di sebagian besar instalasi, untuk memecahkan captcha. Anda mengirim satu POST JSON ke API Scarnox, membaca solution.token dari respons, lalu mengirim token itu ke form situs. Panduan ini memandu alur PHP lengkap untuk PopularCaptcha, yang saat ini di-solve Scarnox secara proxyless.
Mulai dengan kredit uji coba gratis, tanpa kartu dan coba skripnya di halaman yang Anda kontrol sebelum memakainya di tempat lain.
Kebutuhan
- PHP 8.0 atau yang lebih baru, dengan ekstensi
curldanjsonaktif. Periksa denganphp -m. - API key Scarnox.
- Sitekey dari widget PopularCaptcha di halaman tersebut. Untuk bantuan menemukannya, lihat cara mencari sitekey captcha.
Fungsi solver
Fungsi ini mengirim POST ke API, memeriksa errorId, dan mengembalikan token. Fungsi ini melempar exception untuk kegagalan apa pun, sehingga pemanggil bisa memutuskan apakah akan retry:
<?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, // panggilan kembali saat token siap
]);
$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'];
}
Header Authorization memakai awalan Bearer. Timeout-nya 185 detik karena API memblokir sampai token siap, tanpa langkah polling.
Coba ulang kegagalan sementara
Solve yang gagal tidak dikenai biaya, jadi beberapa retry itu murah. Bungkus pemanggilan dengan loop dan tunggu sedikit lebih lama setelah setiap kegagalan:
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;
}
Untuk penanganan error yang lengkap, termasuk kegagalan mana yang harus dihentikan, lihat penanganan error solver captcha.
Kirim token dengan cookie jar
Banyak situs mengikat captcha ke sesi yang memuat form. Sebuah file cookie memungkinkan cURL mengirim cookie yang sama pada GET dan POST. Fungsi di bawah ini mengirimkan token ke form halaman:
function submitToken(string $pageUrl, string $token): string
{
$cookieFile = sys_get_temp_dir() . '/scarnox-cookies.txt';
// GET dulu, agar situs men-set cookie sesi.
$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);
// Lalu POST form dengan token di kedua field captcha.
$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;
}
Ada dua hal yang penting. GET dijalankan sebelum solve agar cookie sudah berada di tempatnya. Dan token dikirim tepat setelah solve, karena token kedaluwarsa dalam sekitar dua menit. Letakkan pemanggilan solve tepat sebelum fungsi ini, bukan di awal batch yang panjang.
File cookie dipakai bersama oleh setiap pemanggilan dalam proses yang sama, jadi berikan setiap akun atau sesi file-nya sendiri jika Anda menjalankan beberapa signup secara paralel. Jika tidak, satu sesi bisa menimpa cookie sesi lain, dan POST kedua akan gagal karena alasan yang terlihat seperti masalah captcha padahal bukan.
Menyatukan semuanya
$pageUrl = 'https://example.com/signup';
$token = solveWithRetry('YOUR-SITEKEY-UUID', $pageUrl);
$html = submitToken($pageUrl, $token);
echo strlen($html) . " bytes returned\n";
Jalankan dari command line:
php signup.php
Captcha invisible
Jika widgetnya invisible, panggil solveCaptcha($sitekey, $pageUrl, true). Field is_invisible kemudian dikirim bersama request. Beberapa halaman juga memerlukan callback JavaScript dipanggil dengan token, yang tidak bisa dipicu oleh script sisi server. Dalam kasus itu, gunakan alat browser sebagai gantinya. Panduan captcha invisible membahas kasus-kasusnya.
Waktu dan kedaluwarsa
Token berlaku sekitar dua menit. Jaga agar solve dan pengiriman tetap berdekatan. Masa berlaku token captcha menjelaskan cara membedakan token yang sudah kedaluwarsa dari token yang ditolak.
Scraping secara bertanggung jawab
Jika script PHP Anda melakukan scraping pada halaman publik, cek robots.txt dan terms situs sebelum mulai. Tambahkan jeda di antara request, dan jangan menyimpan data pribadi yang tidak Anda butuhkan. Memecahkan captcha tidak mengubah apa yang boleh Anda kumpulkan. Untuk sisi hukumnya, lihat apakah web scraping legal.
Harga
Anda membayar per solve yang berhasil. Solve yang gagal tidak dikenai biaya. Lihat harga terkini untuk tarif saat ini, dan mulai dengan kredit uji coba gratis, tanpa kartu.