> 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

Un navegador sin interfaz basado en la nube con seguridad adaptativa integrada, gestión de CAPTCHA y Residential Proxies. Pruébalo con ejemplos de código y personalízalo con funciones avanzadas.

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

## Bibliotecas compatibles

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

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

## Detalles de conexión

{% hint style="warning" %}
**Atención:** Headless Browser se está trasladando a una nueva infraestructura. Actualiza tu cadena de conexión de `UBC.oxylabs.io` a `hb.oxylabs.io` antes de **1 de octubre**. A partir del 1 de octubre, el tráfico enviado al dominio antiguo se redirigirá automáticamente al nuevo.&#x20;

El Dashboard y las herramientas de inspección de sesiones también se han trasladado de `headlesify.io` a `hb.oxylabs.io`. Consulta la [Inspección y grabación de sesiones](/products/es/headless-browser/session-inspection-and-recording.md) para más detalles.
{% endhint %}

<table><thead><tr><th width="161">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>hb.oxylabs.io</code></td></tr><tr><td><strong>Autenticación</strong></td><td>En la URL, la información de usuario – <code>wss://USERNAME:PASSWORD@host</code>. Debe incluir el token de sufijo del 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>Dominio</strong></td><td><code>oxylabs.io</code> – usado para endpoints de conexión (p. ej., <a href="http://hb.oxylabs.io">hb.oxylabs.io</a>), el Dashboard (<a href="http://hb.oxylabs.io/dashboard">hb.oxylabs.io/dashboard</a>), y la inspección de sesiones (<a href="http://hb.oxylabs.io/novnc">hb.oxylabs.io/novnc</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, 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="/products/es/headless-browser/captcha-handling.md"><strong>Manejo de CAPTCHA</strong></a></td><td>Manejo y monitoreo automáticos de CAPTCHA en tiempo real (predeterminado – desactivado).</td></tr><tr><td><a href="/products/es/headless-browser/geolocation-and-proxy-selection.md"><strong>Proxies y geolocalización</strong></a></td><td>Enruta las sesiones a través de países, estados o ciudades específicas.</td></tr><tr><td><a href="/products/es/headless-browser/device-type.md"><strong>Emulación de dispositivos</strong></a></td><td>Emula fingerprints y viewports específicos del dispositivo.</td></tr><tr><td><a href="/products/es/headless-browser/session-inspection-and-recording.md#session-inspection-vnc"><strong>Inspección de sesión (VNC)</strong></a></td><td>Supervisa sesiones en vivo de Headless Browser.</td></tr><tr><td><a href="/products/es/headless-browser/session-inspection-and-recording.md#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="/products/es/headless-browser/persistent-sessions-and-profiles.md#persistent-sessions"><strong>Sesiones persistentes</strong></a></td><td>Crea y administra instancias de navegador sticky.</td></tr><tr><td><a href="/products/es/headless-browser/persistent-sessions-and-profiles.md#persistent-profiles"><strong>Perfiles persistentes</strong></a></td><td>Guarda y restaura cookies/localStorage entre sesiones.</td></tr></tbody></table>

### Pasar parámetros

Todas las funciones se habilitan y configuran agregando parámetros de consulta directamente a tu endpoint WebSocket Secure y encadenando varias funciones usando & (`&`).

```bash
# Ejemplo: conexión a Chrome con geolocalización de US y manejo de CAPTCHA activado
wss://USER:PASS@hb.oxylabs.io?p_cc=US&solve_captcha=true
```

## Ejemplos de código

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

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

```python
from playwright.sync_api import sync_playwright

username = "USERNAME" # include any account suffix
password = "PASSWORD"
endpoint = "hb.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 = "hb.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 = "hb.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 para facilitar la lectura. En proyectos reales, cárgalos desde variables de entorno (p. ej., `process.env.OXYLABS_USERNAME` / `process.env.OXYLABS_PASSWORD`) mediante un  `.env` archivo.
{% endhint %}

{% hint style="warning" %}
**JavaScript:** Usa `NODE_TLS_REJECT_UNAUTHORIZED="0"` el flag antes de requerir Playwright en Node.js si encuentras errores de TLS/certificado. Solo para pruebas locales. En producción, acota la confianza a la conexión específica o agrega 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>). Anula <code>p_cc</code> si se usan ambos. <a href="https://content.gitbook.com/content/BQ7Zf9paoN3FTeGcyfY1/blobs/cVjpiu1GKicluiVIT9og/us_states.txt">Lista de estados compatibles</a>.</td><td>cadena</td></tr><tr><td><code>p_city</code></td><td>Geolocalización de ciudad, en minúsculas, <code>_</code> para los 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>Configura fingerprints, viewports y user-agents del dispositivo. Compatible con <code>escritorio</code> (predeterminado) y <code>móvil</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. Predeterminado: <code>falso</code>.</td><td>booleano</td></tr><tr><td><code>record</code></td><td>Graba el video de la sesión de Headless Browser. Predeterminado: <code>falso</code>.</td><td>booleano</td></tr><tr><td><code>record_name</code></td><td>Nombra la grabación para facilitar su búsqueda (<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, no guiones bajos). TTL máx. – 24h.</td><td>cadena</td></tr><tr><td><code>keep_alive</code></td><td>Mantiene activa la instancia del navegador remoto cuando el cliente se desconecta al establecerse en <code>verdadero</code>. Predeterminado: <code>falso</code>.</td><td>booleano</td></tr><tr><td><code>o_profile</code></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><code>o_profile_save</code></td><td>Perfiles persistentes – fuerza el guardado del perfil durante o al final de la sesión. Predeterminado: <code>falso</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 de Residential Proxies 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>

## Configuración recomendada

### Optimización del tráfico

El scraping de páginas dinámicas a menudo hace que el navegador descargue recursos 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
# Abort heavy assets to save bandwidth and improve speeds
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 intermitentes 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 tiempo de espera. El siguiente ejemplo 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>

Siempre cierra 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 todos los caminos:

```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. Las sesiones filtradas bajo carga pueden agotar el límite y bloquear nuevas conexiones.

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

Algunas funciones de Headless Browser están limitadas de forma predeterminada. Para ajustar tus límites, contacta con soporte de Oxylabs ([chat en vivo](https://oxylabs.io/) o [email](mailto:support@oxylabs.io)) o tu Dedicated Account Manager:

* **Más perfiles persistentes** – aumenta el límite predeterminado de tu cuenta de 5 perfiles guardados.
* **Más sesiones persistentes** – aumenta el límite predeterminado de tu cuenta de 5 sesiones persistentes concurrentes.
* **Objetivos restringidos** – desbloquea más categorías de objetivos mediante el proceso de KYC.
* **Límites de velocidad más altos** – aumenta más allá 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.
