Comparisons

Sticky Session vs Rotating Session: Strategi Proxy Terbaik untuk CAPTCHA

Aturannya pendek: pakai sticky session kalau satu alur menyentuh lebih dari satu halaman (login, checkout, form bertingkat), dan rotating session kalau tiap request berdiri sendiri (daftar produk, pemantauan harga).

Gejala salah pilih khas: task ke in.php sukses, res.php mengembalikan token valid, tetapi form menjawab "verifikasi gagal". Penyebabnya bukan solver, melainkan IP yang berganti antara solve dan submit.


Cara kerja kedua mode sesi

STICKY SESSION:
  Request 1 ──▶ IP: 192.168.1.50 ──▶ site.com/login
  Request 2 ──▶ IP: 192.168.1.50 ──▶ site.com/dashboard
  Request 3 ──▶ IP: 192.168.1.50 ──▶ site.com/account
  (Same IP for all requests in the session window)

ROTATING SESSION:
  Request 1 ──▶ IP: 192.168.1.50 ──▶ site.com/page1
  Request 2 ──▶ IP: 10.0.0.77   ──▶ site.com/page2
  Request 3 ──▶ IP: 172.16.5.22 ──▶ site.com/page3
  (Different IP per request)

Intinya satu: apakah IP Anda bertahan sepanjang jendela sesi, atau diganti tiap request.


Matriks keputusan: mode mana untuk alur kerja apa

Kalau hanya sempat membaca satu tabel, baca ini.

Alur kerja Mode Alasan
Login / pendaftaran Sticky Token terikat pada IP peminta
Checkout / pembayaran Sticky Cookie sesi butuh IP konsisten
Form ber-CAPTCHA Sticky Pengikatan token–IP
Pengambilan banyak halaman Rotating Beban tersebar ke banyak IP
Hasil mesin pencari Rotating Rate limiting per IP
Pemantauan harga Rotating Request saling independen

Faktor pembeda yang menentukan

  • IP per request: sticky menahan satu IP 1–30 menit, rotating mengganti tiap request.
  • Frekuensi tantangan: sticky lebih tenang di alur multi-langkah, rotating lebih tenang di halaman tunggal.
  • Validitas token: sticky lebih aman; rotating berisiko IP tidak cocok saat submit.
  • Risiko IP terblokir: lebih tinggi pada sticky karena request menumpuk di satu alamat.

Kecepatan dan biaya jaringan praktis setara.


Kapan sticky session wajib dipakai

Tanda alur Anda menuntut sticky session:

  • Ada cookie atau header autentikasi yang harus bertahan antar-request.
  • Tantangan muncul di satu halaman, tokennya dipakai di halaman berikutnya.
  • Server menolak dengan pesan sesi tidak valid meski kredensial benar.

Alur multi-langkah dan pengikatan token ke IP

CAPTCHA memvalidasi token terhadap IP peminta. Begitu IP berubah antara pembuatan token dan pengiriman form, server berhak menolaknya — jadi muat halaman, selesaikan tantangan, dan kirim form pada satu IP.

import requests
import time

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"

# Sticky session: same IP for the entire login flow
STICKY_PROXY = {
    "http": "http://user-session-abc123:pass@proxy.example.com:5000",
    "https": "http://user-session-abc123:pass@proxy.example.com:5000",
}

session = requests.Session()
session.proxies = STICKY_PROXY
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
})


def login_with_captcha(url, sitekey, username, password):
    """Full login flow — MUST use same IP throughout."""
    # Step 1: Load login page (IP: 192.168.1.50)
    session.get(url)

    # Step 2: Solve CAPTCHA (solved against IP: 192.168.1.50)
    token = solve_recaptcha(sitekey, url)

    # Step 3: Submit login (MUST be IP: 192.168.1.50)
    resp = session.post(url, data={
        "username": username,
        "password": password,
        "g-recaptcha-response": token,
    })

    return resp.status_code == 200


def solve_recaptcha(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]

    raise TimeoutError("CAPTCHA solve timeout")

Kenapa konsistensi IP menentukan hasil

Sticky session:

  1. Browser loads page    → IP: 5.5.5.5
  2. CAPTCHA solved        → Token bound to session
  3. Form submitted        → IP: 5.5.5.5 ✅ Token accepted

Rotating session:

  1. Browser loads page    → IP: 5.5.5.5
  2. CAPTCHA solved        → Token bound to session
  3. Form submitted        → IP: 9.9.9.9 ❌ Token may be rejected

Aturan praktisnya: satu alur bisnis, satu session ID.

Berapa lama TTL sticky sebaiknya disetel

  • 1 menit — form singkat; berisiko kedaluwarsa di tengah alur.
  • 5 menit — login plus aksi lanjutan; keseimbangan paling aman.
  • 10 menit — alur multi-halaman kompleks; risiko sedang.
  • 30–60 menit — operasi akun panjang; risiko tertinggi.

Setel TTL sekitar dua kali perkiraan waktu alur. Untuk worker di AWS ap-southeast-1 (Singapura) atau ap-southeast-3 (Jakarta), sisakan margin latensi: TTL 5 menit yang longgar di laptop bisa terlalu ketat di produksi.


Kapan rotating session lebih menguntungkan

Pengambilan banyak halaman independen

Setiap halaman berdiri sendiri, tanpa cookie yang perlu dijaga. Rotasi menyebarkan request ke kumpulan IP lebih besar sehingga hitungan per IP rendah.

import concurrent.futures

ROTATING_PROXY = {
    "http": "http://user:pass@rotating.proxy.example.com:5000",
    "https": "http://user:pass@rotating.proxy.example.com:5000",
}


def scrape_page(url):
    """Each request gets a fresh IP automatically."""
    resp = requests.get(
        url,
        proxies=ROTATING_PROXY,
        headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"},
        timeout=30,
    )
    if resp.status_code == 200:
        return url, resp.text
    return url, None


urls = [f"https://example.com/products?page={i}" for i in range(1, 501)]

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as pool:
    results = list(pool.map(scrape_page, urls))
    success = sum(1 for _, html in results if html)
    print(f"Scraped: {success}/{len(urls)}")

Pengambilan hasil mesin pencari

Mesin pencari menghitung volume kueri per IP. Rotasi mencegah hitungan menumpuk di satu alamat:

def scrape_search(query, pages=10):
    results = []
    for page in range(pages):
        # Each request → new IP
        resp = requests.get(
            "https://search-engine.example.com/search",
            params={"q": query, "start": page * 10},
            proxies=ROTATING_PROXY,
            timeout=20,
        )
        results.append(resp.text)
        time.sleep(2)
    return results

Catatan kepatuhan di Indonesia: UU Pelindungan Data Pribadi (UU 27/2022) menjadikan pemilihan target pengambilan data keputusan hukum, bukan sekadar teknis. Ambil hanya data publik yang boleh Anda proses.


Pendekatan hibrid dalam satu pipeline

Kebanyakan pipeline produksi memakai keduanya: sticky untuk bagian ber-state, rotating untuk sisanya.

class HybridProxyManager:
    """Sticky for multi-step flows, rotating for single requests."""

    def __init__(self, provider_host, username, password, port=5000):
        self.host = provider_host
        self.username = username
        self.password = password
        self.port = port

    def get_rotating_proxy(self):
        return {
            "http": f"http://{self.username}:{self.password}@{self.host}:{self.port}",
            "https": f"http://{self.username}:{self.password}@{self.host}:{self.port}",
        }

    def get_sticky_proxy(self, session_id, duration_min=10):
        sticky_user = f"{self.username}-session-{session_id}-ttl-{duration_min}"
        return {
            "http": f"http://{sticky_user}:{self.password}@{self.host}:{self.port}",
            "https": f"http://{sticky_user}:{self.password}@{self.host}:{self.port}",
        }


proxy_mgr = HybridProxyManager("proxy.example.com", "user", "pass")


def scrape_with_auto_strategy(url, needs_login=False):
    if needs_login:
        # Multi-step → sticky
        import uuid
        session_id = uuid.uuid4().hex[:8]
        proxy = proxy_mgr.get_sticky_proxy(session_id)
    else:
        # Single page → rotating
        proxy = proxy_mgr.get_rotating_proxy()

    return requests.get(url, proxies=proxy, timeout=30)

Implementasi Node.js

Pola yang sama dengan axios, lewat satu helper pemilih mode:

const axios = require("axios");

const CAPTCHAAI_KEY = "YOUR_API_KEY";
const PROXY_HOST = "proxy.example.com";
const PROXY_PORT = 5000;

function getProxy(mode, sessionId = null) {
  const user =
    mode === "sticky" ? `user-session-${sessionId}` : "user";

  return {
    proxy: {
      host: PROXY_HOST,
      port: PROXY_PORT,
      auth: { username: user, password: "pass" },
    },
  };
}

// Rotating: bulk scrape
async function scrapePages(urls) {
  const results = [];
  for (const url of urls) {
    const config = getProxy("rotating");
    const resp = await axios.get(url, { ...config, timeout: 30000 });
    results.push({ url, data: resp.data });
  }
  return results;
}

// Sticky: login flow
async function loginFlow(loginUrl, sitekey, credentials) {
  const sessionId = Date.now().toString(36);
  const config = getProxy("sticky", sessionId);

  // Step 1: Load page
  await axios.get(loginUrl, config);

  // Step 2: Solve CAPTCHA
  const submitResp = await axios.post(
    "https://ocr.captchaai.com/in.php",
    null,
    {
      params: {
        key: CAPTCHAAI_KEY,
        method: "userrecaptcha",
        googlekey: sitekey,
        pageurl: loginUrl,
        json: 1,
      },
    }
  );
  const taskId = submitResp.data.request;

  let token;
  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const res = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: CAPTCHAAI_KEY, action: "get", id: taskId, json: 1 },
    });
    if (res.data.request !== "CAPCHA_NOT_READY") {
      token = res.data.request;
      break;
    }
  }

  // Step 3: Submit with same IP
  return axios.post(
    loginUrl,
    {
      ...credentials,
      "g-recaptcha-response": token,
    },
    config
  );
}

Diagnosis cepat saat hasilnya meleset

Lima gejala berikut menutupi hampir semua kasus produksi.

Gejala Penyebab Perbaikan
Token ditolak padahal solve berhasil IP berganti antara solve dan submit Pindah ke sticky
CAPTCHA sering muncul di halaman tunggal Satu IP menyentuh terlalu banyak halaman Pindah ke rotating
Cookie sesi hilang di tengah alur Sticky kedaluwarsa Perbesar TTL
Rotating terasa lambat Overhead koneksi tiap IP Aktifkan connection pooling
IP terblokir saat sticky aktif Request menumpuk di IP tertandai Perpendek TTL

Urutan pemeriksaan yang efisien:

  1. Bandingkan IP keluar tepat sebelum solve dan tepat sebelum submit.
  2. Pastikan TTL sticky masih hidup saat form dikirim.
  3. Baru setelah keduanya bersih, curigai sitekey atau parameter task.

Biaya: yang sebenarnya berubah

Yang bergeser bukan tagihan jaringan, melainkan jumlah tantangan CAPTCHA yang muncul. Penagihan CaptchaAI berbasis thread, bukan per solve — dari BASIC ($15/bulan, 5 thread) sampai VIP-3 ($7,500/bulan, 5.000 thread). Mode yang keliru memperpanjang antrean thread sehingga throughput turun di paket yang sama. Bagi freelancer otomatisasi dan agensi pemantauan harga dengan anggaran tetap per proyek, membenahi mode sesi lebih murah daripada menaikkan paket.

Format session ID berbeda antar penyedia; pengaturannya dibahas terpisah untuk Bright Data, Smartproxy, dan Oxylabs.


Pertanyaan umum

Kenapa token saya valid tetapi form tetap ditolak?

Periksa apakah IP berubah antara solve dan submit: token dibuat untuk satu IP lalu dikirim dari IP lain. Kunci seluruh alur ke satu sticky session.

Berapa lama TTL sticky yang aman untuk alur login?

Mulai dari 5 menit. Naikkan hanya bila alur Anda benar-benar lebih panjang, karena TTL besar menumpuk request di satu IP.

Bisakah dua mode dipakai dalam satu proyek?

Bisa, dan itu pola yang disarankan: sticky untuk autentikasi, rotating untuk pengumpulan data, seperti HybridProxyManager di atas.

Tipe CAPTCHA apa saja yang bisa ditangani pada alur seperti ini?

  • reCAPTCHA v2 dan v3, Cloudflare Turnstile, GeeTest v3.
  • CaptchaFox (beta), Friendly Captcha (beta), Lemin (beta).
  • hCaptcha dan FunCaptcha tidak didukung; GeeTest v4 berstatus segera hadir.

Bacaan lanjutan

Lanjutan yang paling sering dibutuhkan: rotasi egress jaringan yang diotorisasi, pengaruh kualitas jaringan pada tingkat keberhasilan solve, dan cara menjaga state sesi browser.


Cocokkan mode sesi dengan alur kerja Anda — ambil API key CaptchaAI dan ukur sendiri selisihnya.

Komentar dinonaktifkan untuk artikel ini.