Tutorials

Mobile Browser Automation CAPTCHA Solving with CaptchaAI

Mobile browser automation encounters the same CAPTCHAs as desktop — reCAPTCHA checkboxes, Cloudflare challenges, image grids — but also faces mobile-specific quirks like responsive layouts, touch-only interactions, and different User-Agent fingerprints. CaptchaAI handles the solving regardless of the device context.

This tutorial covers two approaches: Selenium with Chrome for Android via ADB, and Playwright's mobile emulation on desktop.

Real-World Scenario

You are automating form submissions on a mobile-optimized website that serves reCAPTCHA v2. The site detects mobile User-Agents and renders a mobile-specific CAPTCHA layout. You need to solve the CAPTCHA and submit the form from a mobile browser context.

Approach 1: Playwright Mobile Emulation (Python)

Playwright's device emulation is the simplest way to automate mobile browsers with CAPTCHA solving — no physical device required:

# playwright_mobile_captcha.py
import asyncio
import httpx
from playwright.async_api import async_playwright

API_KEY = "YOUR_API_KEY"

async def solve_recaptcha(sitekey: str, pageurl: str) -> str:
    """Submit reCAPTCHA v2 to CaptchaAI and poll for result."""
    async with httpx.AsyncClient(timeout=180) as client:
        # Submit task
        resp = await client.get(
            "https://ocr.captchaai.com/in.php",
            params={
                "key": API_KEY,
                "method": "userrecaptcha",
                "googlekey": sitekey,
                "pageurl": pageurl,
                "json": "1",
            },
        )
        result = resp.json()
        if result["status"] != 1:
            raise Exception(f"Submit failed: {result['request']}")

        task_id = result["request"]

        # Poll for result
        for _ in range(30):
            await asyncio.sleep(5)
            poll = await client.get(
                "https://ocr.captchaai.com/res.php",
                params={
                    "key": API_KEY,
                    "action": "get",
                    "id": task_id,
                    "json": "1",
                },
            )
            poll_result = poll.json()
            if poll_result["status"] == 1:
                return poll_result["request"]
            if poll_result["request"] != "CAPCHA_NOT_READY":
                raise Exception(f"Solve failed: {poll_result['request']}")

        raise Exception("Polling timeout")

async def main():
    async with async_playwright() as p:
        # Launch with iPhone 13 emulation
        iphone = p.devices["iPhone 13"]
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context(**iphone)
        page = await context.new_page()

        await page.goto("https://example.com/mobile-form")
        await page.wait_for_selector(".g-recaptcha", timeout=10000)

        # Extract sitekey
        sitekey = await page.get_attribute(".g-recaptcha", "data-sitekey")
        pageurl = page.url
        print(f"Found sitekey: {sitekey}")

        # Solve via CaptchaAI
        token = await solve_recaptcha(sitekey, pageurl)
        print(f"Token received: {token[:50]}...")

        # Inject token
        await page.evaluate(f"""
            document.getElementById('g-recaptcha-response').value = '{token}';
            document.getElementById('g-recaptcha-response').style.display = '';
        """)

        # Trigger callback if it exists
        await page.evaluate(f"""
            try {{
                const clients = ___grecaptcha_cfg.clients;
                Object.keys(clients).forEach(k => {{
                    Object.keys(clients[k]).forEach(j => {{
                        if (clients[k][j] && clients[k][j].callback) {{
                            clients[k][j].callback('{token}');
                        }}
                    }});
                }});
            }} catch(e) {{}}
        """)

        # Submit form
        await page.click('button[type="submit"]')
        await page.wait_for_load_state("networkidle")
        print("Form submitted successfully")

        await browser.close()

asyncio.run(main())

Approach 2: Selenium with Mobile Emulation (JavaScript)

Use Selenium with Chrome DevTools Protocol mobile emulation for Node.js workflows:

// selenium_mobile_captcha.js
const { Builder, By, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';

async function solveCaptcha(sitekey, pageurl) {
  // Submit task
  const submitResp = await axios.get('https://ocr.captchaai.com/in.php', {
    params: {
      key: API_KEY,
      method: 'userrecaptcha',
      googlekey: sitekey,
      pageurl: pageurl,
      json: '1',
    },
  });

  if (submitResp.data.status !== 1) {
    throw new Error(`Submit failed: ${submitResp.data.request}`);
  }

  const taskId = submitResp.data.request;

  // Poll for result
  for (let i = 0; i < 30; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const pollResp = await axios.get('https://ocr.captchaai.com/res.php', {
      params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
    });

    if (pollResp.data.status === 1) return pollResp.data.request;
    if (pollResp.data.request !== 'CAPCHA_NOT_READY') {
      throw new Error(`Solve failed: ${pollResp.data.request}`);
    }
  }
  throw new Error('Polling timeout');
}

async function main() {
  // Configure mobile emulation
  const mobileEmulation = {
    deviceMetrics: { width: 390, height: 844, pixelRatio: 3.0 },
    userAgent:
      'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) ' +
      'AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
  };

  const options = new chrome.Options();
  options.setMobileEmulation(mobileEmulation);

  const driver = await new Builder()
    .forBrowser('chrome')
    .setChromeOptions(options)
    .build();

  try {
    await driver.get('https://example.com/mobile-form');
    await driver.wait(until.elementLocated(By.css('.g-recaptcha')), 10000);

    // Extract sitekey
    const captchaEl = await driver.findElement(By.css('.g-recaptcha'));
    const sitekey = await captchaEl.getAttribute('data-sitekey');
    const pageurl = await driver.getCurrentUrl();

    console.log(`Sitekey: ${sitekey}`);

    // Solve CAPTCHA
    const token = await solveCaptcha(sitekey, pageurl);
    console.log(`Token: ${token.substring(0, 50)}...`);

    // Inject token
    await driver.executeScript(`
      document.getElementById('g-recaptcha-response').value = arguments[0];
    `, token);

    // Submit form
    await driver.findElement(By.css('button[type="submit"]')).click();
    console.log('Form submitted');
  } finally {
    await driver.quit();
  }
}

main().catch(console.error);

Mobile-Specific Considerations

Factor Desktop Mobile Impact on CAPTCHA
User-Agent Desktop Chrome/Firefox Mobile Safari/Chrome Some sites serve different CAPTCHA configs by device
Viewport 1920×1080+ 390×844 CAPTCHA widget may render differently
Touch events Mouse events Touch events Some CAPTCHAs validate interaction type
Network Broadband 4G/5G Longer timeouts may be needed

Troubleshooting

Problem Cause Fix
CAPTCHA not rendering in mobile emulation Site detects emulation via navigator.platform Set platform override in DevTools Protocol
g-recaptcha-response textarea not found Mobile layout uses different CAPTCHA rendering Search for textarea by name attribute instead of ID
Token injection works but form still fails Server validates User-Agent consistency Ensure the same User-Agent is used for solving and form submission
Slow page loads in emulation Resource-heavy pages Use --disable-images Chrome flag to speed up loading

FAQ

Should I use real mobile devices or emulation?

Emulation is faster for development and CI/CD. Real devices via Appium or ADB are better for production scenarios where fingerprinting matters.

Does CaptchaAI need to know it's a mobile CAPTCHA?

No. CaptchaAI solves based on the sitekey and page URL. Mobile vs desktop distinction doesn't affect the solving process.

Can I combine mobile emulation with a proxy?

Yes. Both Playwright and Selenium support proxy configuration alongside mobile emulation. Pass the proxy to CaptchaAI as well for consistency.

Next Steps

Start automating mobile CAPTCHA flows — get your CaptchaAI API key and integrate with your mobile automation stack.

Related guides:

Discussions (0)

No comments yet.

Related Posts

Reference CAPTCHA Token Injection Methods Reference
Complete reference for injecting solved CAPTCHA tokens into web pages.

Complete reference for injecting solved CAPTCHA tokens into web pages. Covers re CAPTCHA, Turnstile, and Cloud...

Automation Python reCAPTCHA v2
Apr 08, 2026
Tutorials Pytest Fixtures for CaptchaAI API Testing
Build reusable pytest fixtures to test CAPTCHA-solving workflows with Captcha AI.

Build reusable pytest fixtures to test CAPTCHA-solving workflows with Captcha AI. Covers mocking, live integra...

Automation Python reCAPTCHA v2
Apr 08, 2026
Reference Browser Session Persistence for CAPTCHA Workflows
Manage browser sessions, cookies, and storage across CAPTCHA-solving runs to reduce repeat challenges and maintain authenticated state.

Manage browser sessions, cookies, and storage across CAPTCHA-solving runs to reduce repeat challenges and main...

Automation Python reCAPTCHA v2
Feb 24, 2026
Integrations Browser Profile Isolation + CaptchaAI Integration
Browser profile isolation tools create distinct browser environments with unique fingerprints per session.

Browser profile isolation tools create distinct browser environments with unique fingerprints per session. Com...

Automation Python reCAPTCHA v2
Feb 21, 2026
Comparisons WebDriver vs Chrome DevTools Protocol for CAPTCHA Automation
Compare Web Driver and Chrome Dev Tools Protocol (CDP) for CAPTCHA automation — detection, performance, capabilities, and when to use each with Captcha AI.

Compare Web Driver and Chrome Dev Tools Protocol (CDP) for CAPTCHA automation — detection, performance, capabi...

Automation Python reCAPTCHA v2
Mar 27, 2026
Tutorials Securing CaptchaAI Credentials in Environment Variables
Store Captcha AI API keys securely using environment variables, .env files, Docker secrets, and cloud secret managers instead of hardcoding.

Store Captcha AI API keys securely using environment variables, .env files, Docker secrets, and cloud secret m...

Automation Python reCAPTCHA v2
Feb 12, 2026
Use Cases Event Ticket Monitoring with CAPTCHA Handling
Build an event ticket availability monitor that handles CAPTCHAs using Captcha AI.

Build an event ticket availability monitor that handles CAPTCHAs using Captcha AI. Python workflow for checkin...

Automation Python reCAPTCHA v2
Jan 17, 2026
Explainers reCAPTCHA v2 Invisible: Trigger Detection and Solving
Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters, and handle auto-invoked CAPTCHAs.

Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters,...

Automation Python reCAPTCHA v2
Apr 07, 2026
Use Cases CAPTCHA Solving in Ticket Purchase Automation
How to handle CAPTCHAs on ticketing platforms Ticketmaster, AXS, and event sites using Captcha AI for automated purchasing workflows.

How to handle CAPTCHAs on ticketing platforms Ticketmaster, AXS, and event sites using Captcha AI for automate...

Automation Python reCAPTCHA v2
Feb 25, 2026
Tutorials Caching CAPTCHA Tokens for Reuse
Cache and reuse CAPTCHA tokens with Captcha AI to reduce API calls and costs.

Cache and reuse CAPTCHA tokens with Captcha AI to reduce API calls and costs. Covers token lifetimes, cache st...

Automation Python reCAPTCHA v2
Feb 15, 2026
Tutorials Using Fiddler to Inspect CaptchaAI API Traffic
How to use Fiddler Everywhere and Fiddler Classic to capture, inspect, and debug Captcha AI API requests and responses — filters, breakpoints, and replay for tr...

How to use Fiddler Everywhere and Fiddler Classic to capture, inspect, and debug Captcha AI API requests and r...

Automation Python All CAPTCHA Types
Mar 05, 2026
Tutorials GeeTest Token Injection in Browser Automation Frameworks
how to inject Gee Test v 3 solution tokens into Playwright, Puppeteer, and Selenium — including the three-value response, callback triggering, and form submissi...

Learn how to inject Gee Test v 3 solution tokens into Playwright, Puppeteer, and Selenium — including the thre...

Automation Python Testing
Jan 18, 2026