> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/products/es/agent-browser/manejador-de-paginas.md).

# Manejador de páginas

Deja que Agent Browser identifique cada página, gestione automáticamente los desafíos de acceso y le indique a tu script cuándo la página está lista.

{% hint style="warning" %}
**Se requiere acceso a la cuenta:** las cuentas sin la función habilitada reciben `400: el manejador de páginas no está habilitado para esta cuenta en el handshake` (ver [Códigos de respuesta](/products/es/agent-browser/codigos-de-respuesta.md)).
{% endhint %}

Oxylabs Agent Browser utiliza un manejador de páginas integrado para los desafíos de acceso a sitios web. El `page_handler` parámetro identifica cada página que carga, completa los desafíos compatibles que encuentra y reporta el estado de la página a tu script como un mensaje de ventana.

```bash
wss://USER:PASS@hb.oxylabs.io?p_cc=US&page_handler=true
```

**El manejador de páginas está deshabilitado de forma predeterminada** y debe pasarse en cada conexión y mantenerse idéntico para todas las conexiones al mismo destino, incluidas todas las ejecuciones que comparten un [perfil persistente](/products/es/agent-browser/persistent-sessions-and-profiles.md#persistent-profiles) (perfil `o_profile` o una sesión de proxy persistente `proxy_resi_ses_id`).

<table><thead><tr><th width="133">Parámetro</th><th width="405">Descripción</th><th width="93.5">Tipo</th></tr></thead><tbody><tr><td><code>page_handler</code></td><td>Habilita la identificación de páginas y la gestión automática de desafíos. Valor predeterminado: <code>false</code>.</td><td>booleano</td></tr></tbody></table>

{% hint style="info" %}
Page Handler añade tiempo a las cargas de página, así que habilítalo solo para destinos que muestren desafíos. Si la función no está habilitada para tu cuenta, contacta con [el soporte de Oxylabs.](mailto:support@oxylabs.io)
{% endhint %}

## Estado de la página

Con el manejador de páginas habilitado, el navegador informa el estado de cada página como un `ventana` mensaje:

```javascript
{ source: "oxylabs-runtime", type: "oxylabs-page-status", status: "open" }
```

<table><thead><tr><th width="130.5">Estado</th><th>Descripción</th></tr></thead><tbody><tr><td><code>identificando</code></td><td>La página se está comprobando.</td></tr><tr><td><code>cerrado</code></td><td>Se encontró un desafío y se está gestionando. La página aún no se puede usar.</td></tr><tr><td><code>abierto</code></td><td>La página está lista para usar.</td></tr><tr><td><code>fallido</code></td><td>No se pudo completar el desafío. El mensaje incluye un <code>error</code> campo.</td></tr></tbody></table>

`identificando` y `cerrado` son temporales, así que espera a `abierto` o `fallido`. Una página sin desafío informa `abierto` aproximadamente 8 segundos después de cargarla, y gestionar un desafío suele tardar entre 30 y 45 segundos. Si el estado es `fallido`, cierra la sesión y vuelve a intentarlo con una nueva conexión.

## Seguimiento del estado de la página

La salida de la consola del navegador no se entrega a los clientes de CDP, así que escucha el mensaje de la ventana con un script que se añade antes de que cargue la página y luego espera el estado final:

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

```python
from playwright.sync_api import sync_playwright

username = "USERNAME"
password = "PASSWORD"
endpoint = "hb.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}?p_cc=US&page_handler=true"

# Keep the latest page status in the page
status_listener = """
window.addEventListener("message", (e) => {
  const d = e.data;
  if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
    window.__pageStatus = d.status;
  }
});
"""

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    context = browser.contexts[0] if browser.contexts else browser.new_context()
    context.add_init_script(status_listener)  # add before opening the page
    page = context.new_page()
    page.goto("https://example.com")

    # Wait until the page is ready ("open") or the handler gives up ("failed")
    page.wait_for_function("['open', 'failed'].includes(window.__pageStatus)", timeout=90000)
    print(page.evaluate("window.__pageStatus"), page.title())
    browser.close()
```

{% endtab %}

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

```javascript
import { chromium } from "playwright";

const username = "USERNAME";
const password = "PASSWORD";
const endpoint = "hb.oxylabs.io";
const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=US&page_handler=true`;

// Keep the latest page status in the page
const statusListener = () => {
    window.addEventListener("message", (e) => {
        const d = e.data;
        if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
            window.__pageStatus = d.status;
        }
    });
};

(async () => {
    const browser = await chromium.connectOverCDP(browserUrl);
    const context = browser.contexts()[0] || (await browser.newContext());
    await context.addInitScript(statusListener); // add before opening the page
    const page = await context.newPage();
    await page.goto("https://example.com");

    // Wait until the page is ready ("open") or the handler gives up ("failed")
    await page.waitForFunction(
        () => ["open", "failed"].includes(window.__pageStatus),
        null,
        { timeout: 90000 }
    );
    console.log(await page.evaluate(() => window.__pageStatus), await page.title());
    await browser.close();
})();
```

{% endtab %}

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

```javascript
import puppeteer from "puppeteer";

const username = "USERNAME";
const password = "PASSWORD";
const endpoint = "hb.oxylabs.io";
const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=US&page_handler=true`;

// Keep the latest page status in the page
const statusListener = () => {
    window.addEventListener("message", (e) => {
        const d = e.data;
        if (d?.source === "oxylabs-runtime" && d.type === "oxylabs-page-status") {
            window.__pageStatus = d.status;
        }
    });
};

(async () => {
    const browser = await puppeteer.connect({ browserWSEndpoint: browserUrl });
    const page = await browser.newPage();
    await page.evaluateOnNewDocument(statusListener); // add before opening the page
    await page.goto("https://example.com");

    // Wait until the page is ready ("open") or the handler gives up ("failed")
    await page.waitForFunction(
        () => ["open", "failed"].includes(window.__pageStatus),
        { timeout: 90000 }
    );
    console.log(await page.evaluate(() => window.__pageStatus), await page.title());
    await browser.close();
})();
```

{% endtab %}
{% endtabs %}

### Gestión de desafíos después de la carga de la página

El manejador de páginas gestiona los desafíos que están presentes cuando se carga una página. Un desafío que aparece después, por ejemplo tras un clic o el envío de un formulario, no se gestiona automáticamente. Para gestionarlo, envía un `oxylabs-page-handle` mensaje a la página. El navegador vuelve a comprobar la página, gestiona cualquier desafío que encuentre e informa del estado como antes.

### Servidor MCP y habilidades del agente

Si utilizas un agente de IA o un asistente de programación, te recomendamos encarecidamente aprovechar nuestros sencillos métodos de integración para Oxylabs Agent Browser:

<table data-header-hidden><thead><tr><th width="152"></th><th></th></tr></thead><tbody><tr><td><a href="/ai-workflows/agent-skills.md"><strong>Habilidades del agente</strong></a></td><td>Configura Agent Browser en Claude Code, Cursor y otros asistentes de programación de IA.</td></tr><tr><td><a href="/ai-workflows/mcp.md"><strong>Servidor MCP</strong></a></td><td>Proporciona a los asistentes de IA compatibles con MCP un Agent Browser remoto.</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.oxylabs.io/products/es/agent-browser/manejador-de-paginas.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
