CAPSOLVER
Blog
Cara menyelesaikan Captcha AWS dengan NodeJS

Cara menyelesaikan AWS Captcha dengan NodeJS

Logo of CapSolver

Anh Tuan

Data Science Expert

30-Nov-2025

Di lingkungan web modern, melindungi sumber daya online dari ancaman otomatis sangat penting. AWS Web Application Firewall (WAF) adalah lapisan keamanan yang kuat yang sering mengimplementasikan tantangan atau captchas yang dikelola untuk menyaring bot jahat. Meskipun efektif untuk keamanan, mekanisme ini menimbulkan hambatan signifikan bagi tugas otomatisasi sah, seperti scraping web, pemantauan, atau pengujian.

Panduan lengkap ini menyediakan solusi otomatis yang kuat menggunakan Node.js dan layanan CapSolver. Kami akan memandu Anda melalui persiapan lingkungan, implementasi skrip Node.js modular, dan memanfaatkan tugas khusus CapSolver AntiAwsWafTask untuk melewati skenario Tantangan WAF (HTTP 202) dan Tantangan WAF Captcha (HTTP 405). Di akhir tutorial ini, Anda akan memiliki skrip siap produksi yang mampu mendapatkan kuki aws-waf-token yang diperlukan untuk mengakses konten yang dilindungi.

⚙️ Prasyarat

Sebelum memulai, pastikan Anda memiliki lingkungan dan informasi berikut siap:

  1. Lingkungan Node.js: Node.js terinstal di sistem Anda (versi LTS disarankan).
  2. Kunci API CapSolver: Anda membutuhkan akun CapSolver dan kunci API Anda.
  3. Proxy (Opsional): Jika situs target memiliki pembatasan geografis atau Anda perlu menyembunyikan alamat IP Anda, siapkan proxy HTTP/HTTPS.

🛠️ Langkah Satu: Instalasi Ketergantungan yang Diperlukan

Di direktori proyek Anda, jalankan perintah berikut untuk menginstal modul Node.js yang diperlukan:

bash Copy
npm install axios cheerio
  • axios: Digunakan untuk mengirim permintaan HTTP.
  • cheerio: Digunakan untuk mem-parsing konten HTML dan mengekstrak parameter yang diperlukan untuk tantangan WAF AWS.

💻 Langkah Dua: Implementasi Kode Inti Node.js

Berikut adalah skrip Node.js untuk menyelesaikan Tantangan dan Captcha AWS WAF. Skrip ini secara otomatis mendeteksi kode status yang dikembalikan oleh situs web dan menjalankan tugas CapSolver yang sesuai sebagaimana diperlukan.

Simpan kode berikut sebagai aws_waf_solver.js.

javascript Copy
const axios = require('axios');
const cheerio = require('cheerio');
const { URL } = require('url');

// ⚠️ Konfigurasi: Harap ganti dengan nilai sebenarnya Anda
const CLIENT_KEY = "YOUR_CAPSOLVER_API_KEY"; // Ganti dengan kunci API CapSolver Anda
const PAGE_URL = "https://norway-meetup.aws.wslab.no/"; // Ganti dengan URL situs target
const PROXY = "YOUR_PROXY_ADDRESS"; // Ganti dengan alamat proxy Anda (Format: user:pass@ip:port atau ip:port)

// --- Fungsi Bantuan ---

/**
 * Menunda eksekusi selama jumlah milidetik yang ditentukan
 * @param {number} ms Milidetik
 */
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * Membuat tugas dengan CapSolver
 * @param {object} payload Payload tugas
 * @returns {Promise<object>} Hasil pembuatan tugas
 */
async function createTask(payload) {
    try {
        const res = await axios.post('https://api.capsolver.com/createTask', {
            clientKey: CLIENT_KEY,
            task: payload
        });
        if (res.data.errorId !== 0) {
            throw new Error(`Kesalahan API CapSolver: ${res.data.errorDescription}`);
        }
        return res.data;
    } catch (error) {
        console.error("Gagal membuat tugas CapSolver:", error.message);
        return null;
    }
}

/**
 * Mendapatkan hasil tugas CapSolver hingga tugas selesai
 * @param {string} taskId ID tugas
 * @returns {Promise<object>} Hasil tugas
 */
async function getTaskResult(taskId) {
    if (!taskId) return null;
    console.log(`Menunggu hasil tugas (ID: ${taskId})...`);
    try {
        let success = false;
        let result = null;
        while (!success) {
            await sleep(3000); // Query setiap 3 detik
            const res = await axios.post('https://api.capsolver.com/getTaskResult', {
                clientKey: CLIENT_KEY,
                taskId: taskId
            });

            if (res.data.errorId !== 0) {
                throw new Error(`Kesalahan API CapSolver: ${res.data.errorDescription}`);
            }

            if (res.data.status === "ready") {
                success = true;
                result = res.data;
                console.log("Tugas selesai, solusi diperoleh.");
            } else if (res.data.status === "processing") {
                console.log("Tugas masih diproses...");
            }
        }
        return result;
    } catch (error) {
        console.error("Gagal mendapatkan hasil tugas CapSolver:", error.message);
        return null;
    }
}

// --- Fungsi Penyelesaian Inti ---

/**
 * Menyelesaikan Tantangan AWS WAF (Kode Status 202)
 * @param {string} awsChallengeJS URL JavaScript Tantangan AWS
 * @returns {Promise<string|null>} Nilai kuki AWS WAF yang diselesaikan
 */
async function solveAwsChallenge(awsChallengeJS) {
    console.log("Tantangan AWS WAF terdeteksi (Kode Status 202), memulai penyelesaian...");
    const taskPayload = {
        type: "AntiAwsWafTask",
        websiteURL: PAGE_URL,
        awsChallengeJS,
        proxy: PROXY
    };
    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * Menyelesaikan Tantangan AWS WAF Captcha + (Kode Status 405)
 * @param {string} htmlContent Konten HTML yang berisi parameter Captcha
 * @param {string} awsChallengeJS URL JavaScript Tantangan AWS
 * @returns {Promise<string|null>} Nilai kuki AWS WAF yang diselesaikan
 */
async function solveAwsCaptchaChallenge(htmlContent, awsChallengeJS) {
    console.log("Tantangan Captcha AWS WAF terdeteksi (Kode Status 405), memulai penyelesaian...");
    const $ = cheerio.load(htmlContent);
    const scriptContent = $("script[type='text/javascript']").last().html();

    if (!scriptContent) {
        console.error("Tidak dapat menemukan konten skrip yang berisi parameter Captcha.");
        return null;
    }

    // Gunakan ekspresi reguler untuk mengekstrak parameter kunci
    const keyMatch = /"key":"(.*?)"/.exec(scriptContent);
    const ivMatch = /"iv":"(.*?)"/.exec(scriptContent);
    const contextMatch = /"context":"(.*?)"/.exec(scriptContent);

    const key = keyMatch ? keyMatch[1] : null;
    const iv = ivMatch ? ivMatch[1] : null;
    const context = contextMatch ? contextMatch[1] : null;

    if (!key || !iv || !context) {
        console.error("Gagal mengekstrak semua parameter Captcha yang diperlukan (key, iv, context) dari skrip.");
        return null;
    }

    console.log(`Parameter yang diekstrak: Key=${key}, IV=${iv}, Context=${context}`);

    const taskPayload = {
        type: "AntiAwsWafTask", // CapSolver menggunakan tipe tugas ini secara seragam
        websiteURL: PAGE_URL,
        awsKey: key,
        awsIv: iv,
        awsContext: context,
        awsChallengeJS,
        proxy: PROXY
    };

    const taskData = await createTask(taskPayload);
    if (!taskData) return null;

    const result = await getTaskResult(taskData.taskId);
    if (result && result.solution && result.solution.cookie) {
        return result.solution.cookie;
    }
    return null;
}

/**
 * Fungsi eksekusi utama
 */
async function main() {
    let awsWafCookie = null;
    let initialResponse = null;

    // 1. Permintaan awal ke halaman target
    try {
        console.log(`Meminta halaman target: ${PAGE_URL}`);
        initialResponse = await axios.get(PAGE_URL, {
            headers: {
                // Simulasikan header permintaan browser
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
                "Accept-Encoding": "gzip, deflate, br",
                "Accept-Language": "en-US,en;q=0.9",
                "Cache-Control": "max-age=0",
                "Upgrade-Insecure-Requests": "1"
            },
            // Izinkan pemrosesan kode status 2xx, 3xx, 4xx
            validateStatus: (status) => status >= 200 && status < 500
        });
        console.log(`Kode status respons awal: ${initialResponse.status}`);
    } catch (error) {
        console.error(`Permintaan awal gagal: ${error.message}`);
        return;
    }

    const $ = cheerio.load(initialResponse.data);
    const scriptTags = $('script[src*="token.awswaf.com"]');
    const awsChallengeJS = scriptTags.attr('src');

    if (!awsChallengeJS) {
        console.log("Skrip tantangan AWS WAF tidak terdeteksi. Situs web mungkin tidak dilindungi atau telah melewati.");
        // Jika tidak ada skrip tantangan, gunakan respons awal secara langsung
        if (initialResponse.status === 200) {
            console.log("Situs web dimuat dengan sukses.");
            // console.log(initialResponse.data); // Cetak konten akhir
            return;
        }
    } else {
        console.log(`URL skrip tantangan AWS WAF terdeteksi: ${awsChallengeJS}`);
    }


    // 2. Menentukan dan menyelesaikan tantangan/captcha berdasarkan kode status
    if (initialResponse.status === 202) {
        // Hanya Tantangan AWS WAF
        awsWafCookie = await solveAwsChallenge(awsChallengeJS);
    } else if (initialResponse.status === 405) {
        // Tantangan AWS WAF Captcha +
        awsWafCookie = await solveAwsCaptchaChallenge(initialResponse.data, awsChallengeJS);
    } else if (initialResponse.status === 200) {
        console.log("Situs web dimuat dengan sukses, tidak diperlukan penyelesaian Captcha.");
        // console.log(initialResponse.data); // Cetak konten akhir
        return;
    } else {
        console.log(`Menghadapi kode status yang tidak terduga: ${initialResponse.status}.`);
        return;
    }

    // 3. Meminta halaman target lagi menggunakan kuki yang diperoleh
    if (awsWafCookie) {
        try {
            console.log("\n--- Permintaan Kedua: Menggunakan Kuki AWS WAF ---");
            console.log(`Kuki yang digunakan: ${awsWafCookie}`);

            const finalResponse = await axios.get(PAGE_URL, {
                headers: {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
                    "Cookie": `aws-waf-token=${awsWafCookie}`
                },
                validateStatus: (status) => status === 200 // Harapkan keberhasilan akhir
            });

            console.log(`Kode status respons akhir: ${finalResponse.status}`);
            console.log("Konten situs web berhasil diperoleh!");
            // console.log(finalResponse.data); // Cetak konten akhir
        } catch (error) {
            console.error(`Permintaan akhir gagal: ${error.message}`);
        }
    } else {
        console.log("Gagal memperoleh Kuki AWS WAF, tidak dapat melakukan permintaan kedua.");
    }
}

main();

💡 Ringkasan Titik Penting

Titik Penting Masalah Kode Asli Perbaikan yang Ditingkatkan
Instalasi Ketergantungan Kurangnya cheerio, menggunakan sintaks Python yang salah. Jelas menyatakan kebutuhan untuk menginstal axios dan cheerio, menggunakan penyorotan sintaks bash yang benar.
Jenis Tugas Penggunaan campuran FunCaptchaTaskProxyless dan AntiAwsWafTask. Menggunakan secara seragam tugas AntiAwsWafTask yang direkomendasikan secara resmi oleh CapSolver untuk semua skenario AWS WAF.
Ekstraksi Parameter Logika yang tidak lengkap untuk mengekstrak awsChallengeJS dalam logika 405, dan tidak diekstrak dalam logika 202. Menyamakan ekstraksi awsChallengeJS setelah permintaan awal dalam fungsi main, dan memanggil fungsi penyelesaian berbeda berdasarkan kode status (202 atau 405).
Penanganan Kesalahan Penanganan kesalahan sederhana, kurangnya pemeriksaan kesalahan API dan pesan status tugas. Menambahkan pemeriksaan kesalahan API CapSolver (errorId !== 0) dalam createTask dan getTaskResult, serta memberikan pesan status selama pemrosesan tugas.
Struktur Kode Semua logika dikumpulkan dalam fungsi main, menyebabkan keterbacaan yang buruk. Memisahkan menjadi fungsi bantuan yang jelas (sleep, createTask, getTaskResult) dan fungsi penyelesaian inti (solveAwsChallenge, solveAwsCaptchaChallenge), membuat logika lebih jelas.
Header Permintaan Header asli terlalu berlebihan dan tidak lengkap. Menyederhanakan dan menggunakan header permintaan yang lebih standar yang meniru browser.

❓ Pertanyaan yang Sering Diajukan (FAQ)

Q: Mengapa saya perlu menangani kedua kode status HTTP 202 dan HTTP 405?

A: AWS WAF menggunakan pengukuran keamanan yang berbeda yang menghasilkan kode status HTTP yang berbeda:

  • HTTP 202 (Diterima): Biasanya menunjukkan bahwa Tantangan WAF diperlukan. Ini adalah pemeriksaan keamanan yang lebih ringan yang sering melibatkan menjalankan potongan JavaScript.
  • HTTP 405 (Metode Tidak Diizinkan): Sering menunjukkan bahwa Captcha WAF diperlukan, yang merupakan pemeriksaan yang lebih kompleks yang melibatkan menyelesaikan teka-teki visual atau interaktif, bersama dengan parameter tantangan. Skrip kami dirancang untuk secara otomatis mendeteksi dan menangani kedua skenario ini.

Q: Apakah saya bisa menggunakan skrip ini tanpa proxy?

A: Ya, Anda bisa. Variabel PROXY bersifat opsional. Jika Anda tidak memerlukan proxy, Anda dapat mengatur const PROXY = ""; dalam konfigurasi. Namun, menggunakan proxy berkualitas tinggi sangat disarankan untuk tugas scraping web dan otomatisasi untuk menghindari pemblokiran IP dan memastikan akses yang konsisten.

Q: Apa itu AntiAwsWafTask?

A: AntiAwsWafTask adalah jenis tugas khusus yang disediakan oleh CapSolver yang dirancang khusus untuk menangani mekanisme keamanan AWS WAF. Tugas ini secara cerdas memproses parameter tantangan (termasuk awsKey, awsIv, awsContext, dan awsChallengeJS) yang diekstrak dari halaman yang dilindungi dan mengembalikan kuki aws-waf-token yang valid yang diperlukan untuk melewati perlindungan.

📚 Informasi Lebih Lanjut

✅ Kesimpulan

Panduan ini telah menunjukkan metode yang kuat dan efisien untuk menyelesaikan tantangan dan captchas AWS WAF secara programatis menggunakan Node.js dan CapSolver. Dengan mengimplementasikan skrip modular dan memanfaatkan jenis tugas khusus CapSolver, Anda dapat dengan mulus mengintegrasikan solusi ini ke dalam alur kerja otomatisasi Anda. Kunci keberhasilan terletak pada mengidentifikasi dengan benar kode status WAF (202 atau 405), mengekstrak parameter yang diperlukan, dan menggunakan kue aws-waf-token yang dihasilkan untuk permintaan berikutnya. Pendekatan ini memastikan tugas otomatisasi Anda dapat mengakses konten yang dilindungi oleh AWS WAF secara andal.

Pernyataan Kepatuhan: Informasi yang diberikan di blog ini hanya untuk tujuan informasi. CapSolver berkomitmen untuk mematuhi semua hukum dan peraturan yang berlaku. Penggunaan jaringan CapSolver untuk kegiatan ilegal, penipuan, atau penyalahgunaan sangat dilarang dan akan diselidiki. Solusi penyelesaian captcha kami meningkatkan pengalaman pengguna sambil memastikan kepatuhan 100% dalam membantu menyelesaikan kesulitan captcha selama pengambilan data publik. Kami mendorong penggunaan layanan kami secara bertanggung jawab. Untuk informasi lebih lanjut, silakan kunjungi Syarat Layanan dan Kebijakan Privasi.

Lebih lanjut