블로그로 돌아가기
사용 사례

CAPTCHA Handling Strategies for Browser Automation

How to approach CAPTCHAs in automation workflows, including prevention through better fingerprints, solving services, and workflow design.

Introduction

CAPTCHAs are the most visible form of bot detection. They appear when a system suspects non-human activity. While solving CAPTCHAs is sometimes necessary, the best strategy is reducing their frequency through better browser fingerprints and behavioral patterns.

Why CAPTCHAs Appear

CAPTCHAs are triggered by risk signals, not randomly. Common triggers:

  1. Fingerprint anomalies - Headless browser signals, impossible hardware combinations
  2. Behavioral patterns - Inhuman click speed, no mouse movement, perfect timing
  3. IP reputation - Datacenter IPs, known proxy ranges, previous abuse
  4. Rate patterns - Too many requests in too short a time
  5. Session signals - No cookies, no history, clean browser state

Prevention: Reducing CAPTCHA Frequency

The most effective CAPTCHA strategy is preventing them from appearing.

Better Fingerprints

Use complete, consistent browser profiles:

// Cloud browsers with full profiles reduce CAPTCHA frequency
const browser = await puppeteer.connect({
  browserWSEndpoint:
    'wss://bots.win/ws?apiKey=YOUR_API_KEY&proxy=socks5h://user:pass@residential:1080',
});

Key fingerprint factors:

  • Complete hardware identity - GPU, CPU cores, memory, screen
  • Platform consistency - All signals agree on the same OS and device
  • No automation artifacts - navigator.webdriver === false, no CDP detection
  • Current browser version - Outdated versions receive more scrutiny

Better Behavior

// Add mouse movement before clicks
async function humanClick(page, selector) {
  const element = await page.$(selector);
  const box = await element.boundingBox();

  // Move to element with slight randomization
  await page.mouse.move(
    box.x + box.width * Math.random(),
    box.y + box.height * Math.random(),
    { steps: 10 + Math.floor(Math.random() * 10) }
  );

  // Small delay before clicking
  await page.waitForTimeout(100 + Math.random() * 200);
  await page.mouse.click(
    box.x + box.width / 2,
    box.y + box.height / 2
  );
}

Better Network Identity

  • Use residential proxies instead of datacenter IPs
  • Maintain consistent IP per session
  • Match proxy location to content language

Integration with Solving Services

When CAPTCHAs do appear, solving services provide a scalable solution:

Detection

async function detectCaptcha(page) {
  // Check for reCAPTCHA
  const recaptcha = await page.$('iframe[src*="recaptcha"]');
  if (recaptcha) return 'recaptcha';

  // Check for hCaptcha
  const hcaptcha = await page.$('iframe[src*="hcaptcha"]');
  if (hcaptcha) return 'hcaptcha';

  // Check for Cloudflare Turnstile
  const turnstile = await page.$('iframe[src*="turnstile"]');
  if (turnstile) return 'turnstile';

  return null;
}

Workflow Integration

async function handlePage(page, url) {
  await page.goto(url);

  const captchaType = await detectCaptcha(page);

  if (captchaType) {
    console.log(`CAPTCHA detected: ${captchaType}`);

    // Option 1: Use a solving service
    const solution = await solveCaptcha(page, captchaType);
    await applySolution(page, solution);

    // Option 2: Retry with different profile/proxy
    // await retryWithNewSession(url);
  }

  // Continue with normal automation
  return await extractData(page);
}

Measuring CAPTCHA Rate

Track CAPTCHA frequency to evaluate fingerprint quality:

let totalRequests = 0;
let captchaEncounters = 0;

async function processUrl(url) {
  totalRequests++;

  const browser = await puppeteer.connect({ ... });
  const page = await browser.newPage();
  await page.goto(url);

  if (await detectCaptcha(page)) {
    captchaEncounters++;
  }

  // Log rate periodically
  if (totalRequests % 100 === 0) {
    console.log(`CAPTCHA rate: ${(captchaEncounters / totalRequests * 100).toFixed(1)}%`);
  }
}

A healthy CAPTCHA rate for well-configured automation is under 5%. If your rate is higher, focus on fingerprint and behavioral improvements before investing in solving services.

Best Practices

  1. Prevent before solving - Better fingerprints and behavior reduce CAPTCHA frequency more cost-effectively than solving
  2. Track CAPTCHA rates as a quality metric for your automation setup
  3. Use residential proxies to reduce IP-based CAPTCHA triggers
  4. Implement human-like behavior - Mouse movement, realistic timing, scrolling
  5. Maintain sessions - Returning users with cookies get fewer CAPTCHAs than fresh sessions
  6. Diversify profiles - Do not reuse the same fingerprint across too many sessions
#captcha#recaptcha#hcaptcha#automation