Bu makalede tüm önemli sorulara cevap vermeye çalıştık. Bir problemi çözmeye başlamanın ilk adımı, hangi koruma sisteminin kullanıldığını belirlemektir. Bunun için, görsel örneklerin ve neyle karşı karşıya olduğunuzu hızlıca anlamanıza yardımcı olabilecek temel işaretlerin yer aldığı popüler captcha ve anti-bot koruma sistemleri listesine başvurabilirsiniz.
Sitenizde ComplexImage kullanıldığını fark ederseniz, bir sonraki adım özelliklerini ve çalışma şeklini daha ayrıntılı incelemek olacaktır. Yine bu makalede, ComplexImage sisteminin entegrasyonuna ilişkin kılavuzu da bulabilir ve böylece sitenizde nasıl çalıştığını tamamen anlayabilirsiniz. Bu da yalnızca mevcut korumayı anlamanıza değil, aynı zamanda bakımını doğru şekilde planlamanıza da yardımcı olur.
CapMonster Cloud API ile çalışma genellikle şu adımlardan oluşur:
type - ComplexImageTask
class - recognition
imagesBase64 - base64 formatında görüntü dizisi. Örnek: [“/9j/4AAQSkZJRgABAQEAAAAAAAD…”];
Task (metadata içinde) - görev adı (ör. dli).
https://api.capmonster.cloud/createTask{
"clientKey": "API_KEY",
"task": {
"type": "ComplexImageTask",
"class": "recognition",
"imagesBase64": [
"base64"
],
"metadata": {
"Task": "dli" // gereken görevi değiştirin, mevcut modüller listesi https://docs.capmonster.cloud/docs/captchas/ComplexImageTask-Recognition/’te bulunabilir
}
}
}
{
"errorId":0,
"taskId":407533072
}https://api.capmonster.cloud/getTaskResult{
"clientKey":"API_KEY",
"taskId": 407533072
}
{
"solution":
{
"answer": "1",
"metadata": {
"AnswerType": "Text"
}
},
"cost": 0.0003,
"status": "ready",
"errorId": 0,
"errorCode": null,
"errorDescription": null
}
// npm install playwright @zennolab_com/capmonstercloud-client
// npx playwright install chromium
import { chromium } from 'playwright';
import { CapMonsterCloudClientFactory, ClientOptions, ComplexImageTaskRecognitionRequest } from '@zennolab_com/capmonstercloud-client';
const API_KEY = "YOUR_API_KEY";
const TARGET_URL = "https://example.com/captcha-page";
async function solveComplexImageTaskPlaywright() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
await page.goto(TARGET_URL);
// CAPTCHA görüntüsünü bulun
const captchaHandle = await page.$('#captcha'); // gerçek seçici ile değiştirin
const captchaBase64 = await captchaHandle.evaluate(img => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
return canvas.toDataURL('image/png').split(',')[1];
});
console.log("Captcha base64:", captchaBase64.substring(0, 50) + "...");
const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);
// CAPTCHA’yı tanımaya gönder
const citRecognitionRequest = new ComplexImageTaskRecognitionRequest({
imagesBase64: [captchaBase64],
metaData: { Task: 'oocl_rotate' } // CAPTCHA tipinizi değiştirin
});
const result = await cmcClient.Solve(citRecognitionRequest);
console.log("Solution received:", result);
// Çözümün işlenmesi
const solution = result.solution;
if (!solution) {
console.error("No solution received");
return;
}
if (solution.metadata?.AnswerType === "Coordinate") {
// Koordinatlı CAPTCHA
const box = await captchaHandle.boundingBox();
for (const point of solution.answer) {
const clickX = box.x + point.X;
const clickY = box.y + point.Y;
console.log(`Clicking at: (${clickX}, ${clickY})`);
await page.mouse.click(clickX, clickY);
}
} else if (solution.metadata?.AnswerType === "Grid") {
// Grid CAPTCHA (true/false dizisi)
const box = await captchaHandle.boundingBox();
const gridItems = await page.$$('#captcha_grid div'); // grid eleman seçicilerini değiştirin
const answers = solution.answer;
for (let i = 0; i < answers.length; i++) {
if (answers[i] && gridItems[i]) {
const itemBox = await gridItems[i].boundingBox();
const clickX = itemBox.x + itemBox.width / 2;
const clickY = itemBox.y + itemBox.height / 2;
console.log(`Clicking grid item ${i} at: (${clickX}, ${clickY})`);
await page.mouse.click(clickX, clickY);
}
}
} else {
console.warn("Unknown captcha solution type:", solution.metadata?.AnswerType);
}
// Onay butonuna tıklayın (varsa)
await page.click('#submit_button'); // gerçek buton seçici ile değiştirin
console.log("Captcha solved.");
}
solveComplexImageTaskPlaywright().catch(console.error);
1. CAPTCHA’nın sunucuda oluşturulması.
2. CAPTCHA’nın kullanıcıya iletilmesi
<!--Görüntü ızgaralı CAPTCHA-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Grid CAPTCHA Demo</title>
<style>
#captchaGrid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-gap: 10px;
margin-bottom: 10px;
}
.grid-item {
width: 100px;
height: 100px;
background-color: #eee;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 2px solid transparent;
}
.grid-item.selected {
border-color: blue;
}
</style>
</head>
<body>
<h1>Grid CAPTCHA Demo</h1>
<div id="captchaGrid"></div>
<button id="submitBtn">Submit</button>
<button id="refreshBtn">Refresh CAPTCHA</button>
<p id="result"></p>
<script>
let captchaId;
let answers = []; // tıklamalara göre true/false dizisi
async function loadCaptcha() {
const res = await fetch('/captcha'); // sunucu captchaId ve base64 görüntü dizisi içeren JSON döndürmeli
const data = await res.json();
captchaId = data.captchaId;
answers = new Array(data.images.length).fill(false);
const grid = document.getElementById('captchaGrid');
grid.innerHTML = '';
data.images.forEach((imgBase64, i) => {
const div = document.createElement('div');
div.className = 'grid-item';
div.style.backgroundImage = `url('data:image/png;base64,${imgBase64}')`;
div.style.backgroundSize = 'cover';
div.addEventListener('click', () => {
answers[i] = !answers[i];
div.classList.toggle('selected', answers[i]);
});
grid.appendChild(div);
});
document.getElementById('result').textContent = '';
}
document.getElementById('refreshBtn').addEventListener('click', loadCaptcha);
document.getElementById('submitBtn').addEventListener('click', async () => {
const res = await fetch('/captcha/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ captchaId, answer: answers })
});
const data = await res.json();
document.getElementById('result').textContent = data.success ? 'Captcha passed!' : 'Captcha failed, try again.';
if (!data.success) loadCaptcha();
});
// CAPTCHA başlangıçta yüklenir
loadCaptcha();
</script>
</body>
</html>
3. Kullanıcının yanıtı girmesi
4. Yanıtın sunucuya gönderilmesi:
5. Sunucuda doğrulama
<?php
session_start();
// CAPTCHA TTL süresi (saniye)
define('CAPTCHA_TTL', 300); // 5 dakika
// Rastgele görüntü oluştur
function generateCaptchaImage($text = null) {
$width = 100;
$height = 100;
if (!$text) {
$text = substr(str_shuffle('ABCDEFGHJKLMNPQRSTUVWXYZ23456789'), 0, 2);
}
$image = imagecreatetruecolor($width, $height);
// arka plan
$bgColor = imagecolorallocate($image, rand(180, 255), rand(180, 255), rand(180, 255));
imagefilledrectangle($image, 0, 0, $width, $height, $bgColor);
// metin
$textColor = imagecolorallocate($image, 0, 0, 0);
$fontSize = 15;
$fontFile = __DIR__ . '/Arial.ttf'; // TTF font yolu
if (file_exists($fontFile)) {
imagettftext($image, $fontSize, rand(-20,20), 10, 50, $textColor, $fontFile, $text);
} else {
imagestring($image, 5, 10, 40, $text, $textColor);
}
ob_start();
imagepng($image);
$imgData = ob_get_clean();
imagedestroy($image);
return base64_encode($imgData);
}
// Grid CAPTCHA oluştur
function generateGridCaptcha() {
$numImages = 9; // 3x3
$images = [];
$solution = [];
for ($i = 0; $i < $numImages; $i++) {
// Rastgele çöz, doğru görüntü veya değil (örnek)
$isCorrect = rand(0,1) === 1;
$solution[] = $isCorrect;
// Görüntü oluştur (gerçek CAPTCHA için nesneler eklenebilir)
$text = $isCorrect ? 'OK' : 'NO';
$images[] = generateCaptchaImage($text);
}
return ['images' => $images, 'solution' => $solution];
}
// CAPTCHA oluşturma endpoint’i
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/captcha') {
$captchaId = uniqid('captcha_', true);
$gridCaptcha = generateGridCaptcha();
$_SESSION['captchas'][$captchaId] = [
'solution' => $gridCaptcha['solution'],
'timestamp' => time()
];
header('Content-Type: application/json');
echo json_encode([
'captchaId' => $captchaId,
'images' => $gridCaptcha['images']
]);
exit;
}
// CAPTCHA doğrulama endpoint’i
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['REQUEST_URI'] === '/captcha/verify') {
$data = json_decode(file_get_contents('php://input'), true);
$captchaId = $data['captchaId'] ?? '';
$answer = $data['answer'] ?? [];
if (!isset($_SESSION['captchas'][$captchaId])) {
echo json_encode(['success' => false, 'message' => 'Captcha expired or not found']);
exit;
}
$captcha = $_SESSION['captchas'][$captchaId];
// TTL doğrulaması
if (time() - $captcha['timestamp'] > CAPTCHA_TTL) {
unset($_SESSION['captchas'][$captchaId]);
echo json_encode(['success' => false, 'message' => 'Captcha expired']);
exit;
}
// true/false dizisi doğrulaması
$success = $captcha['solution'] === $answer;
// Doğrulama sonrası CAPTCHA’yı sil
unset($_SESSION['captchas'][$captchaId]);
echo json_encode(['success' => $success]);
exit;
}
// 404
http_response_code(404);
echo 'Not found';
6. Sonraki adımlar
Ek
Yük testi yapın (örn: k6 veya JMeter) — çok sayıda istekle:
Siteye önceden kurulmuş CAPTCHA veya başka bir koruma sistemi ile karşılaşırsanız ve koda erişiminiz yoksa endişelenmeyin! Teknolojiyi belirlemek nispeten kolaydır. Doğru çalışmayı test etmek için CapMonster Cloud’u izole test ortamında kullanabilirsiniz; token işleme ve doğrulama mantığının doğru çalıştığını doğrular.
Görsel CAPTCHA için sistemi tanıyın, davranışını inceleyin ve korumanın işlevsel olduğunu doğrulayın. Bu makalede görsel CAPTCHA (ComplexImage) tespit etme ve entegrasyon veya yeniden yapılandırma yollarını gösterdik, böylece korumayı yönetebilir ve izleyebilirsiniz.