> 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/headless-browser.md).

# Headless Browser

Headless Browser te permite ejecutar y controlar instancias remotas para automatización basada en navegador, pruebas y web scraping sin administrarlas localmente. Ofrece seguridad adaptativa integrada, manejo automático de CAPTCHA, geotargeting, proxies residenciales integrados, grabación de sesiones, sesiones sticky y perfiles persistentes.

## Bibliotecas compatibles

Headless Browser funciona con cualquier biblioteca que admita el **Chrome DevTools Protocol (CDP)**, incluidas:

* [Playwright](https://playwright.dev/) (Python y Node.js)
* [Puppeteer](https://pptr.dev/) (Node.js)
* Otros marcos de automatización compatibles con CDP

## Detalles de conexión

<table data-header-hidden><thead><tr><th width="160.5">Campo</th><th>Descripción</th></tr></thead><tbody><tr><td><strong>Protocolo</strong></td><td><code>wss://</code> (WebSocket Secure)</td></tr><tr><td><strong>Host (Chromium)</strong></td><td><code>ubc.oxylabs.io</code></td></tr><tr><td><strong>Autenticación</strong></td><td>En la URL, información de usuario – <code>wss://USERNAME:PASSWORD@host</code>. Debe incluir el token de sufijo de nombre de usuario (p. ej., <code>user_ab12</code>). No se admite la autenticación basada en encabezados.</td></tr><tr><td><strong>Transporte</strong></td><td>CDP – <code>chromium.connectOverCDP</code> (Playwright) / <code>puppeteer.connect</code> (Puppeteer)</td></tr><tr><td><strong>Dominios</strong></td><td><code>oxylabs.io</code> – extremos de conexión a los que te autenticas y conectas (p. ej., <a href="http://ubc.oxylabs.io">ubc.oxylabs.io</a>)<br><code>headlesify.io</code> – panel, inspección de sesiones y grabaciones (p. ej., <a href="http://dashboard.headlesify.io">dashboard.headlesify.io</a>, <a href="http://vnc.headlesify.io">vnc.headlesify.io</a>).</td></tr><tr><td><strong>Límites de tasa</strong></td><td><code>100</code> sesiones concurrentes, <code>10</code> sesión por segundo. <a href="#need-a-feature-enabled-1">Ver más</a>.</td></tr></tbody></table>

## Funciones

Oxylabs Headless Browser incluye funciones integradas y nativas de la nube, diseñadas para usarse mediante parámetros de consulta en la URL de tu conexión WebSocket.

<table data-header-hidden><thead><tr><th width="250"></th><th></th></tr></thead><tbody><tr><td><a href="/pages/3452a8a23df7b292748e47e68bb91e3dcf4f345f"><strong>Manejo de CAPTCHA</strong></a> </td><td>Manejo y monitoreo automáticos de CAPTCHA en tiempo real.</td></tr><tr><td><a href="/pages/a023b5bcc8c5fa34b1c9451714cf98616245ca6e"><strong>Targeting de proxy y geolocalización</strong></a></td><td>Dirige las sesiones a países, estados o ciudades específicos.</td></tr><tr><td><a href="/pages/da020ac8f102b2a0a96de7f4da7dd0edbb400a2d"><strong>Emulación de dispositivos</strong></a></td><td>Emula fingerprints y viewports específicos del dispositivo.</td></tr><tr><td><a href="/pages/a0adad91771991a51bd4a4c18e360239c6721fc6#session-inspection-vnc"><strong>Inspección de sesión (VNC)</strong></a></td><td>Supervisa sesiones de navegador Headless Browser en vivo.</td></tr><tr><td><a href="/pages/a0adad91771991a51bd4a4c18e360239c6721fc6#session-recording"><strong>Grabación de sesión</strong></a> </td><td>Graba sesiones del navegador en formato de video.</td></tr><tr><td><a href="/pages/693756e2c8d8a4ee8cda6dddcd09aba0814f26c1#persistent-sessions"><strong>Sesiones persistentes</strong></a></td><td>Crea y administra instancias de navegador sticky.</td></tr><tr><td><a href="/pages/693756e2c8d8a4ee8cda6dddcd09aba0814f26c1#persistent-profiles"><strong>Perfiles persistentes</strong></a></td><td>Guarda y restaura cookies/localStorage entre sesiones. <em>(</em><a href="#need-a-feature-enabled-1"><em>Se requiere activación</em></a><em>)</em></td></tr></tbody></table>

### Paso de parámetros

Todas las funciones se habilitan y configuran añadiendo parámetros de consulta directamente a tu endpoint de WebSocket Secure, encadenando varias funciones con ampersands (`&`).

```bash
# Ejemplo: conexión a Chrome con geolocalización de EE. UU., manejo de CAPTCHA y flujo VNC en vivo
wss://USER:PASS@ubc.oxylabs.io?p_cc=US&solve_captcha=true&o_vnc=true
```

## Ejemplos de código

A continuación se muestran ejemplos básicos para inicializar una sesión de navegador alojada en la nube:

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

```python
from playwright.sync_api import sync_playwright

username = "USERNAME" # include any account suffix
password = "PASSWORD"
endpoint = "ubc.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}?p_cc=US"

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    page = browser.new_page()
    page.goto("https://ip.oxylabs.io/location")
    print(page.title())
    browser.close()
```

{% endtab %}

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

```javascript
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; //For testing only
import { chromium } from "playwright";

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

(async () => {
    const browser = await chromium.connectOverCDP(browserUrl);
    const ctx = browser.contexts()[0] || (await browser.newContext());
    const page = ctx.pages()[0] || (await ctx.newPage());
    await page.goto("https://ip.oxylabs.io/location");
    console.log(await page.title());
    await browser.close();
})();
```

{% endtab %}

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

```javascript
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; //For testing only
import puppeteer from "puppeteer";

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

(async () => {
    const browser = await puppeteer.connect({ browserWSEndpoint: browserUrl });
    const page = await browser.newPage();
    await page.goto("https://ip.oxylabs.io/location");
    console.log(await page.title());
    await browser.close();
})();
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Nota:** Los ejemplos usan `USERNAME` y `PASSWORD` solo por legibilidad. En proyectos reales, cárgalos desde variables de entorno (p. ej., `process.env.OXYLABS_USERNAME` / `process.env.OXYLABS_PASSWORD`) mediante un archivo `.env` archivo.
{% endhint %}

{% hint style="warning" %}
**JavaScript:** Usa `NODE_TLS_REJECT_UNAUTHORIZED="0"` bandera antes de requerir Playwright en Node.js si encuentras errores de TLS/certificado. Solo para pruebas locales. En producción, limita la confianza a la conexión específica o añade el certificado CA del proveedor a tu almacén de confianza en su lugar.
{% endhint %}

## Referencia de parámetros <a href="#need-a-feature-enabled" id="need-a-feature-enabled"></a>

<table><thead><tr><th width="200">Parámetro</th><th width="431.5">Descripción</th><th>Tipo</th></tr></thead><tbody><tr><td><code>p_cc</code></td><td>Geolocalización del país en <code>ISO 3166-1 alpha-2</code> código de 2 letras (p. ej., <code>US</code>, <code>DE</code>).</td><td>cadena</td></tr><tr><td><code>p_state</code></td><td>Geolocalización del estado en minúsculas (p. ej., <code>texas</code>). Sobrescribe <code>p_cc</code> si se usan ambos. <a href="https://content.gitbook.com/content/BQ7Zf9paoN3FTeGcyfY1/blobs/cVjpiu1GKicluiVIT9og/us_states.txt">Lista de estados admitidos</a>.</td><td>cadena</td></tr><tr><td><code>p_city</code></td><td>Geolocalización de ciudad, en minúsculas, <code>_</code> para espacios (p. ej., <code>new_york</code>). <code>p_cc</code> / <code>p_state</code> obligatorio.</td><td>cadena</td></tr><tr><td><code>p_device</code></td><td>Establece fingerprints del dispositivo, viewports y user-agents. Admite <code>desktop</code> (predeterminado) y <code>mobile</code>.</td><td>cadena</td></tr><tr><td><code>solve_captcha</code></td><td>Resolución automática de CAPTCHA en tiempo real al cargar páginas. Valor predeterminado: <code>true</code>.</td><td>booleano</td></tr><tr><td><code>record</code></td><td>Graba el video de la sesión Headless Browser. Valor predeterminado: <code>false</code>.</td><td>booleano</td></tr><tr><td><code>record_name</code></td><td>Nombra la grabación para encontrarla fácilmente (<code>^[a-zA-Z0-9_-]{1,64}$</code>).</td><td>cadena</td></tr><tr><td><code>session_name</code></td><td>Sesiones sticky – se reconecta al mismo navegador remoto en vivo (<code>^[A-Za-z0-9-]{3,36}$</code>, admite guiones, sin guiones bajos). TTL máximo – 24h.</td><td>cadena</td></tr><tr><td><code>keep_alive</code></td><td>Cierra la instancia remota del navegador al desconectarse el cliente cuando se establece en <code>false</code>. Valor predeterminado: <code>true</code>.</td><td>booleano</td></tr><tr><td><mark style="background-color:yellow;"><code>o_profile</code></mark></td><td>Perfiles persistentes – guarda/restaura cookies y <code>localStorage</code> con un perfil con nombre (<code>^[A-Za-z0-9_-]{1,36}$</code>).</td><td>cadena</td></tr><tr><td><mark style="background-color:yellow;"><code>o_profile_save</code></mark></td><td>Perfiles persistentes – fuerza el guardado del perfil a mitad de sesión. Valor predeterminado: <code>true</code>.</td><td>booleano</td></tr><tr><td><code>proxy_resi_ses_id</code></td><td>ID de sesión personalizado para fijar la IP de salida residencial entre sesiones (<code>^[A-Za-z0-9]{3,36}$</code>).</td><td>cadena</td></tr><tr><td><code>proxy_resi_ses_time</code></td><td>Duración para mantener fijada la IP de salida del proxy residencial en minutos. Mín. <code>1</code>, máx. <code>1440</code> (24h).</td><td>entero</td></tr></tbody></table>

&#x20;    – disponible tras la activación manual para tu cuenta. [Más información](#need-a-feature-enabled-1).

## Configuración recomendada

### Optimización del tráfico

El scraping de páginas dinámicas a menudo hace que el navegador descargue activos innecesarios como medios pesados, scripts de seguimiento, imágenes y fuentes. Esto consume ancho de banda y ralentiza los tiempos de ejecución.

Puedes interceptar y abortar estas solicitudes programáticamente antes de que consuman recursos:

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

```python
# Aborta activos pesados para ahorrar ancho de banda y mejorar la velocidad
def block_resources(route):
    if route.request.resource_type in ["image", "stylesheet", "media", "font"]:
        route.abort()
    else:
        route.continue_()

page.route("**/*", block_resources)
```

{% endtab %}

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

```javascript
// Abort heavy assets to save bandwidth and improve speeds
await page.route("**/*", (route) => {
    const type = route.request().resourceType();
    if (["image", "stylesheet", "media", "font"].includes(type)) {
        return route.abort();
    }
    return route.continue();
});
```

{% endtab %}
{% endtabs %}

### Manejo de errores y reintentos <a href="#error-handling-and-retries" id="error-handling-and-retries"></a>

Los fallos de red y el límite de 10 sesiones por segundo hacen que una sola `connectOverCDP` llamada pueda fallar de forma transitoria. Envuelve la conexión en un `reintento` con `backoff`exponencial, y limita cada intento con un timeout. El ejemplo siguiente usa la API estándar de Playwright:

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

const MAX_RETRIES = 5;
const BASE_DELAY_MS = 1000;

async function connectWithRetry(endpoint, { maxRetries = MAX_RETRIES } = {}) {
    let lastError;
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
            // Cap how long a single connection attempt may take.
            return await chromium.connectOverCDP(endpoint, { timeout: 60_000 });
        } catch (err) {
            lastError = err;
            // Exponential backoff with jitter — backs off when you hit the
            // 10-new-sessions/second rate limit instead of hammering the endpoint.
            const delay = BASE_DELAY_MS * 2 ** attempt + Math.random() * 250;
            console.warn(
                `connect attempt ${attempt + 1} failed: ${err.message}; ` +
                `retrying in ${Math.round(delay)}ms`
            );
            await new Promise((resolve) => setTimeout(resolve, delay));
        }
    }
    throw lastError;
}
```

### Limpieza de recursos <a href="#resource-cleanup" id="resource-cleanup"></a>

Cierra siempre el navegador cuando termines, incluso si tu automatización falla a mitad de camino. Usa un `try { ... } finally { ... }` bloque para que la limpieza se ejecute en cada ruta:

```javascript
const browser = await connectWithRetry(endpoint);
try {
    const ctx = browser.contexts()[0] || (await browser.newContext());
    const page = ctx.pages()[0] || (await ctx.newPage());
    await page.goto("https://ip.oxylabs.io/location");
    // ... your automation ...
} finally {
    // Runs even if the block above throws. Without this, a session left open
    // after an exception lingers and counts against your 100 concurrent-session limit.
    await browser.close();
}
```

Si ocurre una excepción entre connect y close y no limpias, la sesión remota permanece abierta y consume una de tus **100 sesiones concurrentes** hasta que se recupere. Filtrar sesiones bajo carga puede agotar el límite y bloquear nuevas conexiones.

## ¿Necesitas una función habilitada? <a href="#need-a-feature-enabled" id="need-a-feature-enabled"></a>

Algunas funciones de Headless Browser están desactivadas o restringidas por defecto. Para acceder a ellas, contacta con el soporte de Oxylabs ([chat en vivo](https://oxylabs.io/) o [correo electrónico](mailto:support@oxylabs.io)) o con tu gestor de cuenta dedicado:

* **Perfiles persistentes** – obtén acceso a la función y `o_profile` parámetros.
* **Más perfiles** – aumenta el límite `max_profiles` de la cuenta para perfiles persistentes.
* **Destinos restringidos** – desbloquea más categorías de destino mediante el proceso KYC.
* **Límites de tasa más altos** – aumenta por encima de 100 sesiones concurrentes / 10 por segundo.


---

# 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 dynamically by asking a question.

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

```
GET https://developers.oxylabs.io/products/es/headless-browser.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
