logo
bars

画像CAPTCHA (ComplexImage)
と CapMonster Cloud

CAPTCHAの解決、サイトへの設置、テスト。
キャプチャや防御機構が導入済みのサイトを引き継いだのに、ソースコードへアクセスできない? その場合、どの仕組みが入っているのか、設定は正しいのか、どう検証するのかが気になります。

この記事では、よくある疑問にできるだけお答えしました。まず最初のステップは、どのような保護システムが使われているかを特定することです。そのために、代表的なキャプチャやボット対策システムの一覧を参照できます。ここには、どの仕組みが使われているかを素早く見分けるための画面イメージや主な特徴がまとめられています。

もしサイトで ComplexImage が使われていることが分かったら、次のステップはその特徴と動作をより詳しく確認することです。同じこの記事の中で、ComplexImage をサイトに導入するための手順書も確認できるので、あなたのサイト上でどのように機能しているのかをしっかり理解できます。これにより、現在の保護を正しく把握できるだけでなく、今後の運用や保守も計画的に行えるようになります。

画像CAPTCHAとは
画像CAPTCHAとは
画像CAPTCHAは、ユーザーに画像の解析に関連する課題を実行させる視覚的なCAPTCHAの一種です。通常、システムは特定の条件に合う画像を選択する、オブジェクトの数を数える、正しい位置を特定する、またはその他の視覚的操作を行うよう求めます。テキストCAPTCHAでは画像の文字を入力するだけで済みますが、画像CAPTCHAではユーザーが視覚情報を解釈し論理的な操作を行えるかを確認します。そのため、自動認識が難しく、登録やログインなどの重要なポイントをボットから効果的に保護できます。

CapMonster Cloudを使った画像CAPTCHAの解決方法

Tencent CAPTCHAを使用したフォームのテストでは、CAPTCHAが正しく機能し、正しく統合されているかを確認する必要があります。
サイト上のCAPTCHAを手動でテストすることができます:
  • フォームのページを開き、CAPTCHAが表示されていることを確認します。
  • CAPTCHAを解かずにフォームを送信してみてください — サーバーはエラーを返すはずです。
  • CAPTCHAを正しく解いた後、フォームはエラーなく送信されるはずです。
CAPTCHAの自動解決には、CapMonster Cloudなどの専門サービスを使用できます。これはCAPTCHAのパラメータを受け取り、サーバー上で処理し、クリック用の座標や数値など、ユーザーの操作なしで検証を通過できる解答を返します。

CapMonster Cloud API を使った一般的な手順:

タスクの作成タスクの作成
arrow
API リクエストの送信API リクエストの送信
arrow
結果の受信結果の受信
arrow
トークンをページへ適用トークンをページへ適用
arrow
既存ライブラリを使用した画像CAPTCHAの認識
CapMonster Cloudは、PythonJavaScript (Node.js)、C#での利用向けにライブラリを提供しています。
Python
JavaScript
C#
解答の入力とフォーム送信
Node.jsでの例:ウェブページ上でのCAPTCHA認識のフルサイクル。方法としては、HTMLと保護パラメータをHTTPリクエストで取得し、解答を送信して結果を処理するか、例のようにPlaywrightなどの自動化ツールを使ってページを開き、確認待機、CapMonster Cloudクライアントでパラメータ送信、結果取得、適切なフィールドに入力して結果を確認できます。

// 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画像を取得
    const captchaHandle = await page.$('#captcha'); // 実際のセレクターに置き換え
    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を認識に送信
    const citRecognitionRequest = new ComplexImageTaskRecognitionRequest({
        imagesBase64: [captchaBase64],
        metaData: { Task: 'oocl_rotate' } // CAPTCHAタイプを指定
    });

    const result = await cmcClient.Solve(citRecognitionRequest);
    console.log("Solution received:", result);

    // 解答の処理
    const solution = result.solution;

    if (!solution) {
        console.error("No solution received");
        return;
    }

    if (solution.metadata?.AnswerType === "Coordinate") {
        // 座標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") {
        // グリッドCAPTCHA(true/false配列)
        const box = await captchaHandle.boundingBox();
        const gridItems = await page.$$('#captcha_grid div'); // グリッド要素のセレクターを置き換え
        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);
    }

    // 確認ボタンをクリック(存在する場合)
    await page.click('#submit_button'); // 実際のボタンセレクターに置き換え

    console.log("Captcha solved.");
}

solveComplexImageTaskPlaywright().catch(console.error);
  
自サイトに画像CAPTCHAを接続する方法
CAPTCHAの仕組みを理解し、ロジックを確認したり再設定したりするため、このセクションを学習することを推奨します。保護の統合プロセスを説明しており、全体の理解が速くなります。

1. サーバーでCAPTCHA生成

  • CAPTCHA画像を生成:単一画像または画像グリッド。
  • ボット対策としてノイズ、歪み、ランダム要素を追加。
  • ユニークなcaptchaIdを生成し、正解を保存(メモリ、DB、キャッシュ)。

2. CAPTCHAをクライアントに送信

  • サーバーがクライアントにcaptchaIdと画像(base64またはURL)を送信。
  • クライアントはCAPTCHAを表示。例:<img> または <div>グリッドと指示。
クライアント側例(HTML + JS)クライアント側例(HTML + JS)
arrow

3. ユーザーによる解答入力

  • ユーザーはテキスト入力、画像クリック、オブジェクト回転を行う。
  • クライアントは適切な形式で解答を作成:
    • テキストCAPTCHA → 文字列
    • グリッド → true/false 配列
    • 座標 → {X, Y} 配列

4. サーバーへ解答送信:

  • クライアントはcaptchaIdと解答をPOST送信。
  • 複数回の送信防止のため、セッショントークンを送信可能。

5. サーバーでの確認

  • サーバーはcaptchaIdでCAPTCHAセッションを検索。
  • ユーザー解答と正解を比較。
  • success: true/false を返す。
  • 失敗時はCAPTCHAを更新可能。
サーバー側例サーバー側例
arrow

6. 次のステップ

  • CAPTCHA成功 → 保護されたプロセス(フォーム、登録など)許可。
  • CAPTCHA失敗 → 新しいCAPTCHA、試行回数制限可能。

追加の推奨事項

  • CAPTCHAセッションにTTLを設定し、自動的に期限切れにする。
  • 画像をキャッシュし、リソース節約のため一時URLを使用。
  • モバイルでクリックやタッチが正しく動作することを確認。
  • ログと分析を保持し、UXとボット防御を改善。
Background
想定されるエラーとデバッグ
Bug Icon
画像CAPTCHAが読み込まれません
(空のグリッド、壊れた画像、404/500 エラー、base64 の問題) — サーバーが画像を正しく生成していること、base64 データが破損していないこと、画像形式がブラウザでサポートされていること、そしてクライアントが有効な captchaId を受け取っていることを確認してください。
Bug Icon
ユーザーのクリックが処理されません
(セルが選択されない、またはレスポンスが空) — クリックの座標やインデックスがサーバーに送信されていること、データが正しくシリアライズされていること、モバイル端末でタッチイベントがサポートされていることを確認してください。
Bug Icon
正しいクリックでもキャプチャが通りません
検証前にキャプチャが再生成されていないこと、正解がセッションごとに別々に保存されていること、レスポンス形式が期待どおりであること、キャプチャの有効期限(TTL)が切れていないことを確認してください。
Bug Icon
CAPTCHAの有効期限切れ
ユーザーが解くのに時間がかかる場合、TTLを延長し、再試行時にCAPTCHAを更新、画像の再読み込みを通知。
保護の堅牢性チェック
統合後は、システムが本当に自動化された操作からサイトを守れているか確認しましょう。
セキュリティと最適化のヒント
正しい回答は<b>サーバーのみ</b>に保存(メモリ、Redis、DB)、クライアントには絶対渡さない。
ワンタイムCAPTCHA ID (<b>captchaId</b>) を使用。
1つのCAPTCHAの試行回数を制限。
画像とクリックの送信は常に<b>HTTPS</b>を使用。
画像をキャッシュし、可能であれば<b>一時URL</b>を使用。
生成・検証エラーをログ(時刻、IP/fingerprint、拒否理由)記録。
CAPTCHAの仕組みを定期的に更新(画像セット、グリッドサイズ/構造、タスク種類)。
まとめ

既にCAPTCHAや他の保護が設置されたサイトでコードにアクセスできなくても問題ありません。技術の特定は容易です。正しく動作するか確認するには、CapMonster Cloudを隔離テスト環境で使い、トークン処理やロジックが正しく機能しているか確認できます。

画像CAPTCHAの場合、システムを特定し、挙動を学習して保護が機能しているか確認します。この記事では、ComplexImage CAPTCHAの特定方法と接続・再設定方法を示し、保護を維持して機能を管理する方法を紹介しました。

Conclusion
参考リンク
DocIconCapMonster Cloud (ComplexImage) ドキュメントDocIcon自作CAPTCHA作成ガイドDocIconCapMonster Cloud サービス登録