Bir Japon e-ticaret kataloğundan ürün verisi toplarken ya da Korece bir portalda otomatik test yürütürken karşınıza çıkan görüntü CAPTCHA'sı, standart OCR araçlarını anında durdurur. Sebebi basit: Latin alfabesine göre eğitilmiş tanıma motorları hiragana, katakana, kanji veya hangul karakterlerini okuyamaz. CaptchaAI tarafında çözüm tek bir parametreye bakar — language=2. Bu değeri gönderdiğinizde istek, CJK karakter kümeleri üzerinde eğitilmiş modellere yönlendirilir ve Japonca ile Korece görüntü CAPTCHA'ları aynı uç nokta üzerinden çözülür. Bu rehber; çalışan Python ve Node.js kodu, karakter sistemleri arasındaki farklar ve üretimde en sık görülen hataların düzeltmeleriyle bu akışı baştan sona kurar.
Bölgeye göre karşılaşacağınız CAPTCHA türleri
Japonya ve Kore siteleri farklı doğrulama karışımları kullanır. Hangi türle çalıştığınızı bilmek, doğru çözücüyü seçmenin ilk adımıdır.
| Bölge | Sık görülen türler | Karakter setleri | CaptchaAI çözücü |
|---|---|---|---|
| Japonya | Hiragana/katakana içeren görüntü, reCAPTCHA | Hiragana, katakana, kanji, Latince | Resim/OCR |
| Kore | Hangul içeren görüntü, reCAPTCHA, özel kaydırıcılar | Hangul, Latince | Resim/OCR |
| Her ikisi de | reCAPTCHA v2/v3 (yerelleştirilmiş arayüz) | Yok (token tabanlı) | reCAPTCHA |
Bazı Asya sitelerinde hCaptcha da görürsünüz; ancak CaptchaAI hCaptcha'yı henüz desteklemiyor, dolayısıyla bu tür için görüntü/OCR akışını değil sitenin sunduğu alternatif doğrulamayı hedeflemeniz gerekir. Görüntü tabanlı CAPTCHA'lar ve reCAPTCHA ise doğrudan desteklenir.
Python ile Japonca ve Korece resim CAPTCHA çözme
Aşağıdaki fonksiyonlar görüntüyü base64 olarak gönderir, language=2 ile CJK modeline yönlendirir ve sonucu periyodik sorgulamayla toplar. solve_captcha_from_session ise mevcut bir oturum içinde çalışır — giriş yaptıktan sonra aynı çerezlerle CAPTCHA görüntüsünü indirip çözmeniz gerektiğinde bunu kullanın.
import requests
import base64
import time
API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
def solve_japanese_captcha(image_path: str) -> str:
"""Solve a Japanese character image CAPTCHA."""
with open(image_path, "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
resp = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "base64",
"body": image_b64,
"language": 2, # CJK character support
"json": 1,
}, timeout=30).json()
if resp.get("status") != 1:
raise RuntimeError(f"Submit: {resp.get('request')}")
task_id = resp["request"]
for _ in range(24):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve: {poll.get('request')}")
raise RuntimeError("Timeout")
def solve_korean_captcha(image_path: str) -> str:
"""Solve a Korean hangul image CAPTCHA."""
with open(image_path, "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
resp = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "base64",
"body": image_b64,
"language": 2,
"json": 1,
}, timeout=30).json()
if resp.get("status") != 1:
raise RuntimeError(f"Submit: {resp.get('request')}")
task_id = resp["request"]
for _ in range(24):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve: {poll.get('request')}")
raise RuntimeError("Timeout")
def solve_captcha_from_session(session: requests.Session,
captcha_url: str,
language: int = 2) -> str:
"""Download and solve a CAPTCHA within a session context."""
resp = session.get(captcha_url, timeout=15)
image_b64 = base64.b64encode(resp.content).decode()
submit = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "base64",
"body": image_b64,
"language": str(language),
"json": 1,
}, timeout=30).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit: {submit.get('request')}")
task_id = submit["request"]
for _ in range(24):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve: {poll.get('request')}")
raise RuntimeError("Timeout")
# --- Usage ---
# Japanese CAPTCHA
jp_text = solve_japanese_captcha("japanese_captcha.png")
print(f"Japanese CAPTCHA: {jp_text}")
# Korean CAPTCHA from a live session
session = requests.Session()
session.headers["Accept-Language"] = "ko-KR,ko;q=0.9"
session.get("https://example.kr/login") # establish session
kr_text = solve_captcha_from_session(session, "https://example.kr/captcha/image")
print(f"Korean CAPTCHA: {kr_text}")
Japonca ve Korece için ayrı fonksiyonlar yazmak zorunda değilsiniz; ikisi de aynı language=2 değerini kullanır. Örnekteki ayrım yalnızca okunabilirlik içindir — tek bir çözüm fonksiyonu her iki dili de kapsar.
Node.js ile CJK görüntü CAPTCHA çözme
Aynı akışın Node.js karşılığı aşağıdadır. solveAsianCaptcha diskteki bir görüntüyü çözer; solveFromUrl ise CAPTCHA'yı doğrudan URL'den indirip uygun Accept-Language başlığıyla oturum bağlamında çalışır.
const API_KEY = "YOUR_API_KEY";
const SUBMIT_URL = "https://ocr.captchaai.com/in.php";
const RESULT_URL = "https://ocr.captchaai.com/res.php";
const fs = require("fs");
async function solveAsianCaptcha(imagePath) {
const imageB64 = fs.readFileSync(imagePath, "base64");
const body = new URLSearchParams({
key: API_KEY,
method: "base64",
body: imageB64,
language: "2",
json: "1",
});
const resp = await (await fetch(SUBMIT_URL, { method: "POST", body })).json();
if (resp.status !== 1) throw new Error(`Submit: ${resp.request}`);
const taskId = resp.request;
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const url = `${RESULT_URL}?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const poll = await (await fetch(url)).json();
if (poll.request === "CAPCHA_NOT_READY") continue;
if (poll.status === 1) return poll.request;
throw new Error(`Solve: ${poll.request}`);
}
throw new Error("Timeout");
}
async function solveFromUrl(captchaUrl, cookies = "") {
const resp = await fetch(captchaUrl, {
headers: { Cookie: cookies, "Accept-Language": "ja-JP,ja;q=0.9" },
});
const buffer = await resp.arrayBuffer();
const imageB64 = Buffer.from(buffer).toString("base64");
const body = new URLSearchParams({
key: API_KEY, method: "base64", body: imageB64,
language: "2", json: "1",
});
const submitResp = await (await fetch(SUBMIT_URL, { method: "POST", body })).json();
if (submitResp.status !== 1) throw new Error(`Submit: ${submitResp.request}`);
const taskId = submitResp.request;
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const url = `${RESULT_URL}?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const poll = await (await fetch(url)).json();
if (poll.request === "CAPCHA_NOT_READY") continue;
if (poll.status === 1) return poll.request;
throw new Error(`Solve: ${poll.request}`);
}
throw new Error("Timeout");
}
// Usage
const jpText = await solveAsianCaptcha("japanese_captcha.png");
console.log(`Japanese: ${jpText}`);
Karakter sistemleri ve Latin OCR neden yetersiz kalır
Doğru sonuç almak için önce karşınızdaki yazı sistemini tanımanız işe yarar. Japonca tek bir görüntüde üç yazı sistemini birleştirebilir; Korece ise hece bloklarından oluşan hangul kullanır. Latin karakter kümesine göre eğitilmiş klasik OCR, bu setlerin hiçbirini güvenilir okuyamadığı için CJK modeli şarttır.
| Yazı sistemi | Karakterler | Notlar |
|---|---|---|
| Hiragana (ひらがな) | 46 temel karakter | Fonetik; yerli Japonca kelimeler için kullanılır |
| Katakana (カタカナ) | 46 temel karakter | Fonetik; yabancı alıntı kelimeler için kullanılır |
| Kanji (漢字) | Binlerce karakter | Çinceyle paylaşılır; CAPTCHA'lar ortak alt kümeyi kullanır |
| Hangul (한글) | 24 temel harf, ~11.000 hece bloğu | Kore fonetik alfabesi |
| Karışık (JP) | Hiragana + katakana + kanji + Latince | En zorlusu — tek görüntüde birden fazla yazı sistemi |
Karışık yazı sistemli Japonca CAPTCHA'lar en zorlayıcı senaryodur: aynı görüntüde fonetik ve ideografik karakterler bir arada bulunur. language=2 bu karışımı tek çağrıda ele alır, dolayısıyla her yazı sistemi için ayrı istek göndermeniz gerekmez.
Asya pazarına yönelik veri toplamada pratik notlar
Türkiye'deki otomasyon geliştiricilerinin bir kısmı, freelance projelerde Japon ve Korece kaynaklardan fiyat/katalog verisi topluyor. Bu tür işlerde iki nokta öne çıkar. Birincisi maliyet öngörülebilirliği: CaptchaAI planları thread tabanlıdır ve aylık USD olarak sabittir. TL kur dalgalanmasından etkilenmediği için bütçeleme kolaylaşır. Küçük ölçekli işler için BASIC ($15/ay, 5 thread) yeterlidir; paralel kazımada eş zamanlı istek sayısını artırmak isterseniz ADVANCE ($90/ay, 50 thread) gibi daha yüksek thread'li planlara geçebilirsiniz. Tüm planlarda thread başına çözüm sınırsızdır — yani ücret, çözdüğünüz CAPTCHA adedine değil, aynı anda açık tuttuğunuz thread sayısına bağlıdır.
İkincisi uyumluluk. Topladığınız veri kişisel bilgi içeriyorsa KVKK kapsamına girer. CAPTCHA çözümünü yalnızca yetkiniz olan QA ve veri toplama iş akışlarında kullanın; kişisel veri işlerken saklama ve amaç sınırlaması kurallarını göz önünde bulundurun.
Sık karşılaşılan sorunlar ve çözümleri
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Hiragana katakanayla karışıyor | Görsel benzerlik (ör. き vs キ) | language=2 gönderin — CaptchaAI CJK setlerini ayırt eder |
| Hangul karakterleri bozuk geliyor | Yanıt Latin-1 olarak çözülüyor | UTF-8'i zorlayın: response.encoding = 'utf-8' |
| Karışık yazı sistemli CAPTCHA başarısız | Tek görüntüde birden fazla karakter seti | CaptchaAI language=2 ile karışık sistemleri tek çağrıda ele alır |
| Stilize metinde düşük doğruluk | Karakterlerde ağır bozulma | Daha yüksek çözünürlüklü görüntü tanımayı artırır |
| Çözümden sonra oturum süresi doldu | Karmaşık karakterlerde uzun çözüm süresi | Oturumu önceden kurun, hızlı çözün, token'ı hemen gönderin |
Sık sorulan sorular
Asya pazarına yönelik toplu kazıma için hangi CaptchaAI planı yeterli?
Eş zamanlı istek sayınıza bağlıdır. Küçük ölçekli işler için BASIC ($15/ay, 5 thread) yeterlidir; yoğun paralel kazımada ADVANCE ($90/ay, 50 thread) gibi daha yüksek thread'li planlara geçin. Her planda thread başına çözüm sınırsız olduğu için maliyet, çözüm adedine değil eş zamanlı thread sayısına bağlıdır.
CaptchaAI, karakterin Japonca mı Korece mi olduğunu nasıl anlıyor?
language=2 gönderdiğinizde ayrı bir dil seçmenize gerek kalmaz. Model CJK kümesini otomatik algılar; hiragana, katakana, kanji ve hangul aynı parametreyle çözülür. Aradaki tek pratik fark istekteki Accept-Language başlığıdır ve bu da yalnızca sitenin sizi doğru dilde karşılaması içindir.
Hangul yanıtı bozuk geliyorsa ne yapmalıyım?
Genellikle yanıtın Latin-1 olarak çözülmesinden kaynaklanır. HTTP istemcinizde kodlamayı UTF-8'e sabitleyin (response.encoding = 'utf-8') ve karakterler doğru görünecektir. Bu, hangul'da en sık rastlanan görünüm bozukluğudur.
Görüntü çözünürlüğü doğruluğu ne kadar etkiler?
Belirgin biçimde. Kanji ve karışık yazı sistemlerinde küçük ya da ağır bozulmuş görüntüler tanımayı zorlaştırır. Mümkünse yüksek çözünürlüklü görüntü gönderin; bu, çözüm doğruluğunu en çok artıran tek faktördür.
Japon ve Korece sitelerdeki reCAPTCHA'yı da çözebilir miyim?
Evet. reCAPTCHA token tabanlıdır ve dilden bağımsız çalışır; yerelleştirilmiş arayüz çözüm sürecini etkilemez. Sayfadaki sitekey ile CaptchaAI'nin reCAPTCHA çözücüsünü kullanın, akış diğer sitelerdekiyle aynıdır.
İlgili Makaleler
Sonraki adımlar
CJK karakterli görüntü CAPTCHA'larını çözmeye başlamak için CaptchaAI API anahtarınızı alın ve language=2 ile ilk isteğinizi gönderin.
İlgili kılavuzlar: