CAPSOLVER
Blog
Cara Menyelesaikan Captcha di Maxun dengan Integrasi CapSolver

Cara Menyelesaikan Captcha di Maxun dengan Integrasi CapSolver

Logo of CapSolver

Adélia Cruz

Neural Network Developer

21-Jan-2026

Dalam ekstraksi data web, Maxun semakin mendapat perhatian sebagai platform tanpa kode yang terbuka sumbernya yang mempermudah tim dalam mengumpulkan data dari web. Alur kerja berbasis robot dan SDK-nya memungkinkan baik pengembang maupun pengguna non-teknis untuk membangun dan memelihara pipa ekstraksi tanpa usaha teknis yang berat.

Namun, banyak situs web dunia nyata dilindungi oleh CAPTCHA, yang sering menjadi hambatan utama selama ekstraksi data. CapSolver bekerja dengan baik bersama Maxun dengan menangani tantangan ini pada tingkat infrastruktur. Dengan CapSolver, robot Maxun dapat terus beroperasi di halaman yang dilindungi CAPTCHA secara lebih andal, menggabungkan kemudahan penggunaan dengan kemampuan ekstraksi yang praktis dan siap produksi.


Apa itu Maxun?

Maxun adalah platform ekstraksi data web tanpa kode yang terbuka sumbernya yang memungkinkan pengguna melatih robot untuk mengambil data dari situs web tanpa menulis kode. Fiturnya mencakup antarmuka visual untuk pembuatan robot, SDK yang kuat untuk kontrol program, dan mendukung penggunaan di cloud maupun self-hosted.

Fitur Utama Maxun

  • Builder Robot Tanpa Kode: Antarmuka visual untuk melatih robot ekstraksi tanpa pemrograman
  • SDK yang Kuat: SDK TypeScript/Node.js untuk eksekusi robot secara programatik
  • Berbagai Mode Ekstraksi: Kemampuan ekstraksi, pengambilan, crawling, dan pencarian
  • Selector Cerdas: Deteksi elemen otomatis dan pembuatan selector yang cerdas
  • Cloud & Self-Hosted: Deploy di Maxun Cloud atau infrastruktur Anda sendiri
  • Dukungan Proxy: Rotasi dan manajemen proxy terintegrasi
  • Jadwal Berjalan: Otomatisasi eksekusi robot dengan jadwal berbasis cron

Kelas SDK Inti

Kelas Deskripsi
Extract Bangun alur kerja ekstraksi data yang terstruktur dengan LLM atau selector CSS
Scrape Konversi halaman web menjadi Markdown, HTML, atau screenshot yang bersih
Crawl Menemukan dan mengambil halaman secara otomatis menggunakan sitemap dan tautan
Search Lakukan pencarian web dan ekstrak konten dari hasil (DuckDuckGo)

Apa yang Membuat Maxun Berbeda

Maxun menghubungkan antara kesederhanaan tanpa kode dan fleksibilitas pengembang:

  • Visual + Kode: Latih robot secara visual, lalu kendalikan secara programatik via SDK
  • Arsitektur Berbasis Robot: Template ekstraksi yang dapat digunakan kembali dan dibagikan
  • Native TypeScript: Dibangun untuk aplikasi Node.js modern
  • Open Source: Transparansi penuh dan pengembangan yang didorong komunitas

Apa itu CapSolver?

CapSolver adalah layanan penyelesaian CAPTCHA yang terkemuka yang menyediakan solusi berbasis AI untuk melewati berbagai tantangan CAPTCHA. Dengan dukungan untuk berbagai jenis CAPTCHA dan waktu respons yang sangat cepat, CapSolver terintegrasi secara mulus ke dalam alur kerja otomatis.

Jenis CAPTCHA yang Didukung

CapSolver membantu alur kerja otomatis menangani sebagian besar CAPTCHA dan mekanisme anti-bot yang umum ditemui selama ekstraksi web dan otomatisasi browser, termasuk:

Mengapa Mengintegrasikan CapSolver dengan Maxun?

Saat membangun robot Maxun yang berinteraksi dengan situs web yang dilindungi—baik untuk ekstraksi data, pemantauan harga, atau riset pasar—tantangan CAPTCHA menjadi penghalang signifikan. Berikut adalah alasan mengapa integrasi ini penting:

  1. Ekstraksi Data yang Tidak Terputus: Robot dapat menyelesaikan misinya tanpa intervensi manual
  2. Operasi yang Dapat Dikembangkan: Menangani tantangan CAPTCHA di berbagai eksekusi robot yang bersamaan
  3. Alur Kerja yang Mulus: Menyelesaikan CAPTCHA sebagai bagian dari pipa ekstraksi Anda
  4. Biaya Efektif: Bayar hanya untuk CAPTCHA yang berhasil diselesaikan
  5. Tingkat Keberhasilan Tinggi: Akurasi terkemuka industri untuk semua jenis CAPTCHA yang didukung

Instalasi

Prasyarat

  • Node.js 18 atau lebih tinggi
  • npm atau yarn
  • Kunci API CapSolver

Instalasi SDK Maxun

bash Copy
# Instal SDK Maxun
npm install maxun-sdk

# Instal dependensi tambahan untuk integrasi CapSolver
npm install axios

Instalasi Docker (Maxun Self-Hosted)

bash Copy
# Klon repositori Maxun
git clone https://github.com/getmaxun/maxun.git
cd maxun

# Jalankan dengan Docker Compose
docker-compose up -d

Pengaturan Lingkungan

Buat file .env dengan konfigurasi Anda:

env Copy
CAPSOLVER_API_KEY=your_capsolver_api_key
MAXUN_API_KEY=your_maxun_api_key

# Untuk Maxun Cloud (app.maxun.dev)
MAXUN_BASE_URL=https://app.maxun.dev/api/sdk

# Untuk Maxun Self-Hosted (default)
# MAXUN_BASE_URL=http://localhost:8080/api/sdk

Catatan: Konfigurasi baseUrl diperlukan saat menggunakan Maxun Cloud. Instalasi self-hosted secara default menggunakan http://localhost:8080/api/sdk.


Membuat Layanan CapSolver untuk Maxun

Berikut adalah layanan TypeScript yang dapat digunakan kembali yang mengintegrasikan CapSolver dengan Maxun:

Layanan CapSolver Dasar

typescript Copy
import axios, { AxiosInstance } from 'axios';

interface TaskResult {
  gRecaptchaResponse?: string;
  token?: string;
  cookies?: Array<{ name: string; value: string }>;
  userAgent?: string;
}

interface CapSolverConfig {
  apiKey: string;
  timeout?: number;
  maxAttempts?: number;
}

class CapSolverService {
  private client: AxiosInstance;
  private apiKey: string;
  private maxAttempts: number;

  constructor(config: CapSolverConfig) {
    this.apiKey = config.apiKey;
    this.maxAttempts = config.maxAttempts || 60;

    this.client = axios.create({
      baseURL: 'https://api.capsolver.com',
      timeout: config.timeout || 30000,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  private async createTask(taskData: Record<string, unknown>): Promise<string> {
    const response = await this.client.post('/createTask', {
      clientKey: this.apiKey,
      task: taskData,
    });

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

    return response.data.taskId;
  }

  private async getTaskResult(taskId: string): Promise<TaskResult> {
    for (let attempt = 0; attempt < this.maxAttempts; attempt++) {
      await this.delay(2000);

      const response = await this.client.post('/getTaskResult', {
        clientKey: this.apiKey,
        taskId,
      });

      const { status, solution, errorDescription } = response.data;

      if (status === 'ready') {
        return solution as TaskResult;
      }

      if (status === 'failed') {
        throw new Error(`Tugas gagal: ${errorDescription}`);
      }
    }

    throw new Error('Waktu menunggu solusi CAPTCHA habis');
  }

  private delay(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  async solveReCaptchaV2(websiteUrl: string, websiteKey: string): Promise<string> {
    const taskId = await this.createTask({
      type: 'ReCaptchaV2TaskProxyLess',
      websiteURL: websiteUrl,
      websiteKey,
    });

    const solution = await this.getTaskResult(taskId);
    return solution.gRecaptchaResponse || '';
  }

  async solveReCaptchaV3(
    websiteUrl: string,
    websiteKey: string,
    pageAction: string = 'submit'
  ): Promise<string> {
    const taskId = await this.createTask({
      type: 'ReCaptchaV3TaskProxyLess',
      websiteURL: websiteUrl,
      websiteKey,
      pageAction,
    });

    const solution = await this.getTaskResult(taskId);
    return solution.gRecaptchaResponse || '';
  }

  async solveTurnstile(
    websiteUrl: string,
    websiteKey: string,
    action?: string,
    cdata?: string
  ): Promise<string> {
    const taskData: Record<string, unknown> = {
      type: 'AntiTurnstileTaskProxyLess',
      websiteURL: websiteUrl,
      websiteKey,
    };

    // Tambahkan metadata opsional
    if (action || cdata) {
      taskData.metadata = {};
      if (action) (taskData.metadata as Record<string, string>).action = action;
      if (cdata) (taskData.metadata as Record<string, string>).cdata = cdata;
    }

    const taskId = await this.createTask(taskData);
    const solution = await this.getTaskResult(taskId);
    return solution.token || '';
  }

  async checkBalance(): Promise<number> {
    const response = await this.client.post('/getBalance', {
      clientKey: this.apiKey,
    });

    return response.data.balance || 0;
  }
}

export { CapSolverService, CapSolverConfig, TaskResult };

★ Insight ─────────────────────────────────────
Layanan CapSolver menggunakan pola polling (getTaskResult) karena penyelesaian CAPTCHA bersifat asinkron—API menerima tugas, memprosesnya di server mereka, dan mengembalikan hasilnya ketika siap. Penundaan 2 detik antar polling menyeimbangkan responsivitas dengan batas API.
─────────────────────────────────────────────────


Menyelesaikan Berbagai Jenis CAPTCHA

reCAPTCHA v2 dengan Maxun

Karena Maxun beroperasi pada tingkat yang lebih tinggi daripada otomatisasi browser mentah, pendekatan integrasi fokus pada penyelesaian CAPTCHA sebelum atau selama eksekusi robot:

typescript Copy
import { Extract } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';

const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const extractor = new Extract({
  apiKey: MAXUN_API_KEY,
  baseUrl: MAXUN_BASE_URL,
});

async function extractWithRecaptchaV2() {
  const targetUrl = 'https://example.com/protected-page';
  const recaptchaSiteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';

  console.log('Menyelesaikan reCAPTCHA v2...');

  // Selesaikan CAPTCHA terlebih dahulu
  const token = await capSolver.solveReCaptchaV2(targetUrl, recaptchaSiteKey);

  console.log('CAPTCHA diselesaikan, membuat robot ekstraksi...');

  // Buat robot menggunakan chaining metode
  const robot = await extractor
    .create('Product Extractor')
    .navigate(targetUrl)
    .type('#g-recaptcha-response', token)
    .click('button[type="submit"]')
    .wait(2000)
    .captureList({ selector: '.product-item' });

  // Jalankan robot
  const result = await robot.run({ timeout: 30000 });

  console.log('Ekstraksi selesai:', result.data);
  return result.data;
}

extractWithRecaptchaV2().catch(console.error);

reCAPTCHA v3 dengan Maxun

typescript Copy
import { Extract } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';

const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const extractor = new Extract({
  apiKey: MAXUN_API_KEY,
  baseUrl: MAXUN_BASE_URL,
});

async function extractWithRecaptchaV3() {
  const targetUrl = 'https://example.com/v3-protected';
  const recaptchaSiteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDEF';

  console.log('Menyelesaikan reCAPTCHA v3 dengan skor tinggi...');

  // Selesaikan dengan aksi halaman khusus
  const token = await capSolver.solveReCaptchaV3(
    targetUrl,
    recaptchaSiteKey,
    'submit'  // pageAction
  );

  console.log('Token diperoleh dengan skor tinggi, membuat robot...');

  // Buat robot ekstraksi menggunakan chaining metode
  const robot = await extractor
    .create('V3 Protected Extractor')
    .navigate(targetUrl)
    .type('input[name="g-recaptcha-response"]', token)
    .click('#submit-btn')
    .wait(2000)
    .captureText({ resultData: '.result-data' });

  const result = await robot.run({ timeout: 30000 });

  console.log('Data diekstrak:', result.data);
  return result.data;
}

extractWithRecaptchaV3().catch(console.error);

Cloudflare Turnstile dengan Maxun

typescript Copy
import { Scrape } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const CAPSOLVER_API_KEY = process.env.CAPSOLVER_API_KEY!;
const MAXUN_API_KEY = process.env.MAXUN_API_KEY!;
const MAXUN_BASE_URL = process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk';

const capSolver = new CapSolverService({ apiKey: CAPSOLVER_API_KEY });
const scraper = new Scrape({
  apiKey: MAXUN_API_KEY,
  baseUrl: MAXUN_BASE_URL,
});

async function extractWithTurnstile() {
  const targetUrl = 'https://example.com/turnstile-protected';
  const turnstileSiteKey = '0x4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxGHI';

  console.log('Menyelesaikan Cloudflare Turnstile...');

  // Selesaikan dengan metadata opsional (action dan cdata)
  const token = await capSolver.solveTurnstile(
    targetUrl,
    turnstileSiteKey,
    'login',                              // action opsional
    '0000-1111-2222-3333-example-cdata'  // cdata opsional
  );

  console.log('Turnstile diselesaikan, membuat robot scraping...');

  // Buat robot scraping - untuk Turnstile, biasanya kita perlu
  // mengirim token via POST terlebih dahulu, lalu scraping
  const robot = await scraper.create('turnstile-scraper', targetUrl, {
    formats: ['markdown', 'html'],
  });

  const result = await robot.run({ timeout: 30000 });

  console.log('Ekstraksi selesai');
  console.log('Markdown:', result.data.markdown?.substring(0, 500));
  return result.data;
}

extractWithTurnstile().catch(console.error);

Integrasi dengan Alur Kerja Maxun

Menggunakan dengan Kelas Extract

Kelas Extract digunakan untuk menarik data terstruktur dari elemen halaman tertentu. Ini mendukung ekstraksi yang didukung LLM (dengan prompt alami) dan non-LLM (dengan selector CSS):

typescript Copy
import { Extract } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const extractor = new Extract({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});

interface ProductData {
  name: string;
  price: string;
  rating: string;
}

async function extractProductsWithCaptcha(): Promise<ProductData[]> {
const targetUrl = 'https://example.com/products';
  const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';

  // Selesaikan CAPTCHA terlebih dahulu
  const captchaToken = await capSolver.solveReCaptchaV2(targetUrl, siteKey);

  console.log('CAPTCHA selesai, membuat robot ekstraksi...');

  // Membuat robot ekstraksi menggunakan metode chaining
  const robot = await extractor
    .create('Pengumpul Produk')
    .navigate(targetUrl)
    .type('#g-recaptcha-response', captchaToken)
    .click('button[type="submit"]')
    .wait(3000)
    .captureList({
      selector: '.product-card',
      pagination: { type: 'clickNext', selector: '.next-page' },
      maxItems: 50,
    });

  // Jalankan ekstraksi
  const result = await robot.run({ timeout: 60000 });

  return result.data.listData as ProductData[];
}

extractProductsWithCaptcha()
  .then((products) => {
    products.forEach((product) => {
      console.log(`${product.name}: ${product.price}`);
    });
  })
  .catch(console.error);

★ Wawasan ─────────────────────────────────────
Metode captureList dalam kelas Extract Maxun secara otomatis mendeteksi bidang dalam item daftar dan menangani navigasi halaman. Ketika Anda menentukan jenis navigasi halaman (scrollDown, clickNext, atau clickLoadMore), robot akan terus mengekstrak hingga mencapai batas Anda atau habisnya halaman.
─────────────────────────────────────────────────

Menggunakan dengan Kelas Scrape

Kelas Scrape mengubah halaman web menjadi HTML bersih, Markdown yang siap untuk LLM, atau screenshot:

typescript Copy
import { Scrape } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
import axios from 'axios';

const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const scraper = new Scrape({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});

interface ScrapeResult {
  url: string;
  markdown?: string;
  html?: string;
  captchaSolved: boolean;
}

async function scrapeWithCaptchaHandling(): Promise<ScrapeResult[]> {
  const urls = [
    'https://example.com/page1',
    'https://example.com/page2',
    'https://example.com/page3',
  ];

  const results: ScrapeResult[] = [];

  for (const url of urls) {
    try {
      // Untuk halaman yang dilindungi CAPTCHA, selesaikan terlebih dahulu dan buat sesi
      const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC'; // Dapatkan secara dinamis jika diperlukan

      console.log(`Menyelesaikan CAPTCHA untuk ${url}...`);
      const captchaToken = await capSolver.solveReCaptchaV2(url, siteKey);

      // Kirim CAPTCHA untuk mendapatkan kuki sesi
      const verifyResponse = await axios.post(`${url}/verify`, {
        'g-recaptcha-response': captchaToken,
      });

      // Membuat robot scrape untuk halaman yang sudah diotentikasi
      const robot = await scraper.create(`scraper-${Date.now()}`, url, {
        formats: ['markdown', 'html'],
      });

      const result = await robot.run({ timeout: 30000 });

      results.push({
        url,
        markdown: result.data.markdown,
        html: result.data.html,
        captchaSolved: true,
      });

      // Bersihkan - hapus robot setelah digunakan
      await robot.delete();

    } catch (error) {
      console.error(`Gagal mengambil ${url}:`, error);
      results.push({ url, captchaSolved: false });
    }
  }

  return results;
}

scrapeWithCaptchaHandling().then(console.log).catch(console.error);

Menggunakan dengan Kelas Crawl

Kelas Crawl secara otomatis menemukan dan mengambil halaman web menggunakan sitemap dan mengikuti tautan:

typescript Copy
import { Crawl } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';
import axios from 'axios';

const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const crawler = new Crawl({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});

interface PageResult {
  url: string;
  title: string;
  text: string;
  wordCount: number;
}

async function crawlWithCaptchaProtection(): Promise<PageResult[]> {
  const startUrl = 'https://example.com';
  const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';

  // Selesaikan CAPTCHA untuk akses domain
  console.log('Menyelesaikan CAPTCHA untuk akses domain...');
  const captchaToken = await capSolver.solveReCaptchaV2(startUrl, siteKey);

  // Kirim CAPTCHA untuk membuat sesi (spesifik situs)
  await axios.post(`${startUrl}/verify`, {
    'g-recaptcha-response': captchaToken,
  });

  // Membuat robot crawl dengan konfigurasi berbasis domain
  const robot = await crawler.create('site-crawler', startUrl, {
    mode: 'domain',           // Ruang lingkup crawl: 'domain', 'subdomain', atau 'path'
    limit: 50,                // Jumlah maksimum halaman yang diambil
    maxDepth: 3,              // Seberapa dalam mengikuti tautan
    useSitemap: true,         // Parsing sitemap.xml untuk URL
    followLinks: true,        // Mengekstrak dan mengikuti tautan halaman
    includePaths: ['/blog/', '/docs/'],  // Pola regex untuk termasuk
    excludePaths: ['/admin/', '/login/'], // Pola regex untuk mengecualikan
    respectRobots: true,      // Hormati robots.txt
  });

  // Jalankan crawl
  const result = await robot.run({ timeout: 120000 });

  // Setiap halaman dalam hasil berisi: metadata, html, text, wordCount, links
  return result.data.crawlData.map((page: any) => ({
    url: page.metadata.url,
    title: page.metadata.title,
    text: page.text,
    wordCount: page.wordCount,
  }));
}

crawlWithCaptchaProtection()
  .then((pages) => {
    console.log(`Mengambil ${pages.length} halaman`);
    pages.forEach((page) => {
      console.log(`- ${page.title}: ${page.url} (${page.wordCount} kata)`);
    });
  })
  .catch(console.error);

Pola Pre-Authentication

Untuk situs yang membutuhkan CAPTCHA sebelum mengakses konten, gunakan alur kerja pre-authentication:

typescript Copy
import axios from 'axios';
import { Extract } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const extractor = new Extract({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});

interface SessionCookies {
  name: string;
  value: string;
  domain: string;
}

async function preAuthenticateWithCaptcha(
  loginUrl: string,
  siteKey: string
): Promise<SessionCookies[]> {
  // Langkah 1: Selesaikan CAPTCHA
  const captchaToken = await capSolver.solveReCaptchaV2(loginUrl, siteKey);

  // Langkah 2: Kirim token CAPTCHA untuk mendapatkan kuki sesi
  const response = await axios.post(
    loginUrl,
    {
      'g-recaptcha-response': captchaToken,
    },
    {
      withCredentials: true,
      maxRedirects: 0,
      validateStatus: (status) => status < 400,
    }
  );

  // Langkah 3: Ekstrak kuki dari respons
  const setCookies = response.headers['set-cookie'] || [];
  const cookies: SessionCookies[] = setCookies.map((cookie: string) => {
    const [nameValue] = cookie.split(';');
    const [name, value] = nameValue.split('=');
    return {
      name: name.trim(),
      value: value.trim(),
      domain: new URL(loginUrl).hostname,
    };
  });

  return cookies;
}

async function extractWithPreAuth() {
  const loginUrl = 'https://example.com/verify';
  const targetUrl = 'https://example.com/protected-data';
  const siteKey = '6LcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxABC';

  // Pre-authentikasi untuk mendapatkan kuki sesi
  const sessionCookies = await preAuthenticateWithCaptcha(loginUrl, siteKey);

  console.log('Sesi berhasil dibuat, membuat robot ekstraksi...');

  // Membuat robot ekstraksi menggunakan metode chaining
  // Catatan: Gunakan setCookies() untuk mengirimkan kuki sesi yang sudah diotentikasi
  const robot = await extractor
    .create('Pengumpul Terotentikasi')
    .setCookies(sessionCookies)
    .navigate(targetUrl)
    .wait(2000)
    .captureText({ content: '.protected-content' });

  // Jalankan ekstraksi
  const result = await robot.run({ timeout: 30000 });

  return result.data;
}

extractWithPreAuth().then(console.log).catch(console.error);

★ Wawasan ─────────────────────────────────────
Pola pre-authentication memisahkan penyelesaian CAPTCHA dari ekstraksi data. Ini terutama berguna untuk Maxun karena beroperasi pada tingkat abstraksi yang lebih tinggi—alih-alih menyisipkan token ke DOM, Anda membuat sesi yang sudah diotentikasi terlebih dahulu, lalu biarkan robot Maxun bekerja dalam sesi tersebut.
─────────────────────────────────────────────────


Eksekusi Robot Paralel dengan Penanganan CAPTCHA

Kelola CAPTCHA di berbagai eksekusi robot secara bersamaan:

typescript Copy
import { Scrape } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

const capSolver = new CapSolverService({ apiKey: process.env.CAPSOLVER_API_KEY! });
const scraper = new Scrape({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: process.env.MAXUN_BASE_URL || 'https://app.maxun.dev/api/sdk',
});

interface ExtractionJob {
  url: string;
  siteKey?: string;
}

interface ExtractionResult {
  url: string;
  data: { markdown?: string; html?: string };
  captchaSolved: boolean;
  duration: number;
}

async function processJob(job: ExtractionJob): Promise<ExtractionResult> {
  const startTime = Date.now();

  let captchaSolved = false;

  // Selesaikan CAPTCHA jika site key diberikan
  if (job.siteKey) {
    console.log(`Menyelesaikan CAPTCHA untuk ${job.url}...`);
    const token = await capSolver.solveReCaptchaV2(job.url, job.siteKey);
    captchaSolved = true;
    // Token akan dikirimkan untuk membuat sesi sebelum mengambil
  }

  // Membuat dan menjalankan robot scrape
  const robot = await scraper.create(`scraper-${Date.now()}`, job.url, {
    formats: ['markdown', 'html'],
  });

  const result = await robot.run({ timeout: 30000 });

  // Bersihkan robot setelah digunakan
  await robot.delete();

  return {
    url: job.url,
    data: {
      markdown: result.data.markdown,
      html: result.data.html,
    },
    captchaSolved,
    duration: Date.now() - startTime,
  };
}

async function runParallelExtractions(
  jobs: ExtractionJob[],
  concurrency: number = 5
): Promise<ExtractionResult[]> {
  const results: ExtractionResult[] = [];
  const chunks: ExtractionJob[][] = [];

  // Bagi tugas menjadi chunk untuk kontrol konkurensi
  for (let i = 0; i < jobs.length; i += concurrency) {
    chunks.push(jobs.slice(i, i + concurrency));
  }

  for (const chunk of chunks) {
    const chunkResults = await Promise.all(chunk.map(processJob));
    results.push(...chunkResults);
  }

  return results;
}

// Contoh penggunaan
const jobs: ExtractionJob[] = [
  { url: 'https://site1.com/data', siteKey: '6Lc...' },
  { url: 'https://site2.com/data' },
  { url: 'https://site3.com/data', siteKey: '6Lc...' },
  // ... lebih banyak tugas
];

runParallelExtractions(jobs, 5)
  .then((results) => {
    const solved = results.filter((r) => r.captchaSolved).length;
    console.log(`Selesai ${results.length} ekstraksi, selesaikan ${solved} CAPTCHA`);

    results.forEach((r) => {
      console.log(`${r.url}: ${r.duration}ms`);
    });
  })
  .catch(console.error);

Praktik Terbaik

1. Penanganan Kesalahan dengan Pengulangan

typescript Copy
async function solveWithRetry<T>(
  solverFn: () => Promise<T>,
  maxRetries: number = 3
): Promise<T> {
  let lastError: Error | undefined;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await solverFn();
    } catch (error) {
      lastError = error as Error;
      console.warn(`Percobaan ${attempt + 1} gagal: ${lastError.message}`);

      // Backoff eksponensial
      await new Promise((resolve) =>
        setTimeout(resolve, Math.pow(2, attempt) * 1000)
      );
    }
  }

  throw new Error(`Maksimal pengulangan tercapai: ${lastError?.message}`);
}

// Penggunaan
const token = await solveWithRetry(() =>
  capSolver.solveReCaptchaV2(url, siteKey)
);

2. Manajemen Keseimbangan

typescript Copy
async function ensureSufficientBalance(minBalance: number = 1.0): Promise<void> {
  const balance = await capSolver.checkBalance();

  if (balance < minBalance) {
    throw new Error(
      `Saldo CapSolver tidak cukup: $${balance.toFixed(2)}. Silakan recharge.`
    );
  }

  console.log(`Saldo CapSolver: $${balance.toFixed(2)}`);
}

// Periksa saldo sebelum memulai tugas ekstraksi
await ensureSufficientBalance(5.0);

3. Cache Token

typescript Copy
interface CachedToken {
  token: string;
  timestamp: number;
}

class TokenCache {
  private cache = new Map<string, CachedToken>();
  private ttlMs: number;

  constructor(ttlSeconds: number = 90) {
    this.ttlMs = ttlSeconds * 1000;
  }

  private getKey(domain: string, siteKey: string): string {
    return `${domain}:${siteKey}`;
  }

  get(domain: string, siteKey: string): string | null {
    const key = this.getKey(domain, siteKey);
    const cached = this.cache.get(key);

    if (!cached) return null;

    if (Date.now() - cached.timestamp > this.ttlMs) {
      this.cache.delete(key);
      return null;
    }

    return cached.token;
  }

  set(domain: string, siteKey: string, token: string): void {
    const key = this.getKey(domain, siteKey);
    this.cache.set(key, { token, timestamp: Date.now() });
  }
}

const tokenCache = new TokenCache(90);

async function getCachedOrSolve(
  url: string,
  siteKey: string
): Promise<string> {
  const domain = new URL(url).hostname;

  const cached = tokenCache.get(domain, siteKey);
  if (cached) {
    console.log('Menggunakan token yang sudah dicache');
    return cached;
  }

  const token = await capSolver.solveReCaptchaV2(url, siteKey);
  tokenCache.set(domain, siteKey, token);

  return token;
}

Opsi Konfigurasi

Maxun mendukung konfigurasi melalui variabel lingkungan dan opsi SDK:

Pengaturan Deskripsi Default
MAXUN_API_KEY Kunci API Maxun Anda -
MAXUN_BASE_URL URL dasar API Maxun http://localhost:8080/api/sdk (self-hosted) atau https://app.maxun.dev/api/sdk (cloud)
CAPSOLVER_API_KEY Kunci API CapSolver Anda -
CAPSOLVER_TIMEOUT Waktu tunggu permintaan dalam ms 30000
CAPSOLVER_MAX_ATTEMPTS Jumlah maksimal polling 60

Konfigurasi SDK

typescript Copy
import { Extract, Scrape, Crawl, Search } from 'maxun-sdk';
import { CapSolverService } from './capsolver-service';

// Untuk Maxun Cloud (app.maxun.dev)
const MAXUN_BASE_URL = 'https://app.maxun.dev/api/sdk';

// Untuk Maxun self-hosted (default)
// const MAXUN_BASE_URL = 'http://localhost:8080/api/sdk';

// Konfigurasi modul SDK Maxun
const extractor = new Extract({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: MAXUN_BASE_URL,
});
const scraper = new Scrape({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: MAXUN_BASE_URL,
});
const crawler = new Crawl({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: MAXUN_BASE_URL,
});
const searcher = new Search({
  apiKey: process.env.MAXUN_API_KEY!,
  baseUrl: MAXUN_BASE_URL,
});

// Konfigurasi CapSolver
const capSolver = new CapSolverService({
apiKey: process.env.CAPSOLVER_API_KEY!,
  timeout: 30000,
  maxAttempts: 60,
});

Kesimpulan

Mengintegrasikan CapSolver dengan Maxun menciptakan kombinasi yang kuat untuk ekstraksi data web dalam skala besar. Meskipun arsitektur robot Maxun menyederhanakan otomatisasi browser tingkat rendah, CapSolver memberikan kemampuan penting untuk mengatasi tantangan CAPTCHA yang sebelumnya akan menghambat alur ekstraksi Anda.

Kunci keberhasilan integrasi adalah memahami bahwa Maxun beroperasi pada tingkat abstraksi yang lebih tinggi daripada alat otomatisasi browser tradisional. Alih-alih manipulasi DOM langsung untuk penyisipan token CAPTCHA, integrasi ini fokus pada:

  1. Pre-authentication: Selesaikan CAPTCHA sebelum eksekusi robot untuk membangun sesi
  2. Bypass berbasis cookie: Kirim token yang telah diselesaikan dan cookie ke robot Maxun
  3. Pemrosesan paralel: Kelola CAPTCHA secara efisien di berbagai ekstraksi yang berjalan bersamaan

Baik Anda sedang membangun sistem pemantauan harga, alur penelitian pasar, atau platform agregasi data, kombinasi Maxun + CapSolver menyediakan keandalan dan skalabilitas yang diperlukan untuk lingkungan produksi.


Siap mulai? Daftar untuk CapSolver dan gunakan kode bonus MAXUN untuk bonus tambahan 6% pada recharge pertama Anda!


FAQ

Apa itu Maxun?

Maxun adalah platform ekstraksi data web berbasis open-source dan tanpa kode yang memungkinkan pengguna untuk melatih robot agar mengambil data dari situs web tanpa menulis kode. Platform ini memiliki pembangun robot visual, SDK TypeScript/Node.js yang kuat, dan mendukung penyebaran cloud maupun self-hosted.

Bagaimana CapSolver terintegrasi dengan Maxun?

CapSolver terintegrasi dengan Maxun melalui pola pre-authentication. Anda menyelesaikan CAPTCHA melalui API CapSolver sebelum menjalankan robot Maxun, lalu mengirimkan token atau cookie sesi yang dihasilkan ke alur ekstraksi Anda. Pendekatan ini bekerja dengan baik dengan abstraksi tingkat tinggi Maxun.

Jenis CAPTCHA apa yang dapat diselesaikan oleh CapSolver?

CapSolver mendukung berbagai jenis CAPTCHA seperti reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile, Cloudflare Challenge (5s), AWS WAF, GeeTest v3/v4, dan banyak lainnya.

Berapa biaya CapSolver?

CapSolver menawarkan harga kompetitif berdasarkan jenis dan volume CAPTCHA yang diselesaikan. Kunjungi capsolver.com untuk detail harga terkini. Gunakan kode MAXUN untuk bonus 6% pada recharge pertama Anda.

Bahasa pemrograman apa yang didukung oleh Maxun?

SDK Maxun dibangun dalam TypeScript dan berjalan di Node.js 18+. Platform ini menyediakan API modern dan aman tipe untuk kontrol robot secara programatik dan dapat diintegrasikan ke dalam aplikasi Node.js apa pun.

Apakah Maxun gratis untuk digunakan?

Maxun open-source dan gratis untuk self-host. Maxun juga menawarkan layanan cloud dengan fitur tambahan dan infrastruktur yang dikelola. Periksa halaman harga mereka untuk detailnya.

Bagaimana cara menemukan kunci situs CAPTCHA?

Kunci situs biasanya ditemukan dalam sumber HTML halaman. Cari:

  • reCAPTCHA: atribut data-sitekey pada elemen .g-recaptcha
  • Turnstile: atribut data-sitekey pada elemen .cf-turnstile
  • Atau periksa permintaan jaringan untuk kunci dalam panggilan API

Apakah Maxun dapat menangani sesi yang terotentikasi?

Ya, Maxun mendukung cookie dan header kustom dalam konfigurasi robot. Anda dapat mengirimkan cookie sesi yang diperoleh dari penyelesaian CAPTCHA untuk mengotentikasi robot ekstraksi Anda.

Apa perbedaan antara Maxun dan Playwright/Puppeteer?

Maxun beroperasi pada tingkat abstraksi yang lebih tinggi. Meskipun Playwright dan Puppeteer menyediakan kontrol browser tingkat rendah, Maxun fokus pada alur kerja robot yang dapat digunakan kembali yang dapat dibuat secara visual atau programatik. Hal ini membuatnya lebih mudah dalam membangun dan memelihara alur kerja ekstraksi dalam skala besar.

Lebih banyak panduan integrasi untuk dibaca:
Playwright & Puppeteer

Bagaimana cara menangani CAPTCHA yang muncul selama ekstraksi?

Untuk CAPTCHA yang muncul selama ekstraksi (bukan di muatan awal halaman), Anda mungkin perlu mengimplementasikan mekanisme deteksi dalam alur kerja robot dan memicu penyelesaian CAPTCHA saat terdeteksi. Pertimbangkan fitur webhook atau callback Maxun untuk menghentikan dan melanjutkan ekstraksi.

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

Maxun dengan Integrasi CapSolver
Cara Menyelesaikan Captcha di Maxun dengan Integrasi CapSolver

Panduan praktis untuk mengintegrasikan CapSolver dengan Maxun dalam penggunaan nyata pengambilan data web. Pelajari cara mengelola reCAPTCHA, Cloudflare Turnstile, dan situs yang dilindungi CAPTCHA dengan menggunakan alur kerja pre-auth dan robot.

web scraping
Logo of CapSolver

Adélia Cruz

21-Jan-2026

Browser4 dengan Integrasi CapSolver
Cara menyelesaikan Captcha di Browser4 dengan integrasi CapSolver

Otomasi Browser4 dengan throughput tinggi dikombinasikan dengan CapSolver untuk menangani tantangan CAPTCHA dalam ekstraksi data web skala besar.

web scraping
Logo of CapSolver

Anh Tuan

21-Jan-2026

Apa Itu Bot Scraping dan Cara Membuatnya
Apa itu Bot Scraping dan Bagaimana Cara Membuatnya

Pelajari apa itu bot scraping dan cara membuatnya untuk ekstraksi data otomatis. Jelajahi alat terbaik, teknik navigasi keamanan, dan praktik scraping yang etis.

web scraping
Logo of CapSolver

Emma Foster

16-Jan-2026

Scrapy vs. Selenium
Scrapy vs. Selenium: Mana yang Terbaik untuk Proyek Scraping Web Anda?

Temukan kekuatan dan perbedaan antara Scrapy dan Selenium untuk pengambilan data web. Pelajari alat mana yang paling sesuai dengan proyek Anda dan cara mengatasi tantangan seperti CAPTCHA.

web scraping
Logo of CapSolver

Emma Foster

14-Jan-2026

Cara Menggunakan Selenium Driverless untuk Web Scraping
Cara Menggunakan Selenium Driverless untuk Pengambilan Data Web yang Efisien

Pelajari cara menggunakan Selenium Driverless untuk pengambilan data web yang efisien. Panduan ini memberikan instruksi langkah demi langkah tentang menyiapkan lingkungan Anda, menulis skrip Selenium Driverless pertama Anda, dan menangani konten dinamis. Mempermudah tugas pengambilan data web Anda dengan menghindari kompleksitas manajemen WebDriver tradisional, sehingga membuat proses ekstraksi data Anda lebih sederhana, lebih cepat, dan lebih portabel.

web scraping
Logo of CapSolver

Aloísio Vítor

14-Jan-2026

Agno dengan Integrasi CapSolver
Cara Menyelesaikan Captcha di Agno dengan Integrasi CapSolver

Pelajari cara mengintegrasikan CapSolver dengan Agno untuk menyelesaikan tantangan reCAPTCHA v2/v3, Cloudflare Turnstile, dan WAF dalam agen AI otonom. Termasuk contoh Python nyata untuk pengambilan data web dan otomatisasi.

web scraping
Logo of CapSolver

Emma Foster

13-Jan-2026