# Manejo de eventos de CAPTCHA

### Método basado en eventos&#x20;

Para monitorear el proceso de resolución del CAPTCHA, recomendamos usar el método basado en eventos. Permite que tu script escuche mensajes personalizados enviados directamente desde la extensión.

#### Cómo funciona

La extensión envía un mensaje al `window` objeto del navegador. Puedes capturarlos añadiendo un listener de evento "message".

|                               |                                                     |
| ----------------------------- | --------------------------------------------------- |
| `oxylabs-captcha-solve-start` | El CAPTCHA se detectó y la resolución ha comenzado. |
| `oxylabs-captcha-solve-end`   | El CAPTCHA se resolvió correctamente.               |
| `oxylabs-captcha-solve-error` | El auto-solver no pudo omitir el CAPTCHA.           |

Puedes suscribirte a estos eventos para pausar tu automatización y reanudarla solo después de que el CAPTCHA se haya gestionado correctamente. Normalmente, la resolución del CAPTCHA tarda hasta 30 segundos, según el tipo y la complejidad del CAPTCHA, pero en algunos casos puede tardar más, así que deja tiempo para que termine la resolución del CAPTCHA.

#### Ejemplos de código

{% tabs %}
{% tab title="Python (Playwright)" %}

```python
import sys
from playwright.sync_api import sync_playwright

# Configuration
EXTENSION_NAME = 'oxylabs-runtime'
CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end'
CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error'
UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io'
CAPTCHA_CHECK_TIMEOUT_SEC = 60
TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date'

def run():
    with sync_playwright() as p:
        print('Abriendo la página del navegador...')
        # Connect to the remote browser using CDP
        browser = p.chromium.connect_over_cdp(UB_BROWSER_URL)
        
        # Get the default context and create a new page
        ctx = browser.contexts[0]
        page = ctx.new_page()

        # This must be done BEFORE navigation.
        ctx.add_init_script(f"""
            window.addEventListener("message", (event) => {{
                if (event.data && event.data.source === "{EXTENSION_NAME}") {{
                    window.__extensionStatus = event.data.type;
                }}
            }});
        """)

        print('Abriendo el sitio web de destino...')
        page.goto(TARGET_URL, wait_until='domcontentloaded')

        try:
            # Wait for the extension status to change
            page.wait_for_function(
                """
                ([solveEnd, solveError]) => {
                    const status = window.__extensionStatus;
                    if (status === solveError) {
                        throw new Error("CAPTCHA solving failed");
                    }
                    return status === solveEnd;
                }
                """,
                arg=[CAPTCHA_SOLVE_END, CAPTCHA_SOLVE_ERROR],
                timeout=CAPTCHA_CHECK_TIMEOUT_SEC * 1000
            )
            print('CAPTCHA resuelto correctamente, continúa el scraping...')
            
        except Exception as err:
            print(f'Error durante la resolución del CAPTCHA: {err}')
            browser.close()
            sys.exit(1)

        page.wait_for_selector('h1[data-testid="PageHeader-title-reviews"]')
        page.screenshot(path='page_screenshot.jpg')

        page.close()
        browser.close()
        print('Hecho.')

if __name__ == "__main__":
    run()
```

{% endtab %}

{% tab title="JavaScript (Playwright)" %}

```javascript
const { chromium } = require('playwright');

const 
    EXTENSION_NAME = 'oxylabs-runtime',
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io',
    CAPTCHA_CHECK_TIMEOUT_SEC = 60,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';

(async () => {
    console.log('Abriendo la página del navegador...');
    const browser = await chromium.connectOverCDP(UB_BROWSER_URL);
    const ctx = browser.contexts()[0];
    const page = await ctx.newPage();

    // This must be done BEFORE navigation.
    await ctx.addInitScript((extensionName) => {
        window.addEventListener("message", (e) => {
            if (e.data?.source !== extensionName) return;
            window.__extensionStatus = e.data.type;
        });
    }, EXTENSION_NAME);

    console.log('Abriendo el sitio web de destino...');
    await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });

    try {
        await page.waitForFunction(
            ([solveEnd, solveError]) => {
                const status = window.__extensionStatus;
                if (status === solveError) {
                    throw new Error("CAPTCHA solving failed");
                }
                return status === solveEnd;
            },
            [CAPTCHA_SOLVE_END, CAPTCHA_SOLVE_ERROR],
            { timeout: CAPTCHA_CHECK_TIMEOUT_SEC * 1000 }
        );
        console.log('CAPTCHA resuelto correctamente, continúa el scraping...');
    } catch (err) {
        console.error('Error durante la resolución del CAPTCHA:', err.message);
        await browser.close();
        process.exit(1);
    }

    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    await page.screenshot({ path: 'page_screenshot.jpg' });

    await page.close();
    await browser.close();
    console.log('Hecho.');
})();

```

{% endtab %}

{% tab title="JavaScript (Puppeteer)" %}

```javascript
const puppeteer = require('puppeteer');

const 
    EXTENSION_NAME = 'oxylabs-runtime', 
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io',
    CAPTCHA_CHECK_TIMEOUT_SEC = 60,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';

(async () => {
    console.log('Abriendo la página del navegador...');
    
    const browser = await puppeteer.connect({
        browserWSEndpoint: UB_BROWSER_URL,
    });
    const page = await browser.newPage();

    // This must be done BEFORE navigation.
    await page.evaluateOnNewDocument((extensionName) => {
        window.addEventListener("message", (e) => {
            if (e.data?.source !== extensionName) return;
            window.__extensionStatus = e.data.type;
        });
    }, EXTENSION_NAME);

    console.log('Abriendo el sitio web de destino...');
    await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });

    try {
        await page.waitForFunction(
            (solveEnd, solveError) => {
                const status = window.__extensionStatus;
                if (status === solveError) {
                    throw new Error("CAPTCHA solving failed");
                }
                return status === solveEnd;
            },
            { timeout: CAPTCHA_CHECK_TIMEOUT_SEC * 1000 },
            CAPTCHA_SOLVE_END, 
            CAPTCHA_SOLVE_ERROR
        );
        console.log('CAPTCHA resuelto correctamente, continúa el scraping...');
    } catch (err) {
        console.error('Error durante la resolución del CAPTCHA:', err.message);
        await browser.close();
        process.exit(1);
    }

    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    await page.screenshot({ path: 'page_screenshot.jpg' });

    await page.close();
    await browser.disconnect();
    console.log('Hecho.');
})();

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.oxylabs.io/products/es/headless-browser/features/handling-captcha-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
