Volver al blog

Cómo usar un proxy con Playwright: La guía esencial

James Thompson
James Thompson

Scraping and Proxy Management Expert

29-Jun-2026

TL;DR:

  • Playwright controla un proxy a partir de una opción de configuración. El parámetro proxy toma un servidor, nombre de usuario y contraseña, y la misma estructura funciona ya sea que inicies un navegador local o te conectes a uno remoto.
  • Una salida residencial es lo que hace que el tráfico sin cabeza se lea como humano. Los rangos de IP de datacenter y la huella digital de automatización predeterminada son las dos señales que los sitios públicos verifican primero; enrutar a través de direcciones residenciales reales elimina la primera.
  • El Scrapeless Scraping Browser habla el Protocolo de DevTools de Chrome. Playwright se conecta a él con chromium.connectOverCDP(endpoint), por lo que los proxies residenciales y la anti-detención funcionan en la nube mientras tu script permanece como Playwright simple.
  • proxyCountry fija la región de salida; sessionName más sessionTTL mantienen una IP a través de las navegaciones. La geo-targeting y las sesiones pegajosas son parámetros de consulta en la cadena de conexión, no código adicional de aplicación.
  • Ejecuciones paralelas se escalan a través de sesiones independientes. Abre varias conexiones a la vez y cada una obtiene su propia IP residencial, sin límite de asientos concurrentes.
  • Gratis para comenzar. Las nuevas cuentas de Scrapeless incluyen tiempo de ejecución gratuito del Scraping Browser: regístrate en app.scrapeless.com.

Introducción: Proxies de Playwright, y dónde se detiene la configuración en crudo

Playwright controla Chromium, Firefox y WebKit desde una sola API, y su espera automática hace que las navegaciones sean menos frágiles que la generación anterior de herramientas de automatización. Dos cosas aún bloquean un script de Playwright. El navegador envía una huella digital de automatización que los scripts de detección leen, y se conecta desde cualquier IP que tenga la máquina host — usualmente una dirección en la nube o datacenter que los sitios públicos limitan o georestringen. Un proxy residencial responde a la mitad de ese problema en la red; un navegador anti-detección responde a la mitad de la huella digital.

Esta guía comienza con el propio soporte de proxy de Playwright, ya que esa es la opción a la que se conecta cada proxy. Luego muestra dónde se queda sin opciones la configuración de proxy en crudo, y cómo entregar los casos más difíciles a un navegador en la nube al que Playwright se conecta a través del mismo protocolo que ya utiliza para Chromium.


Requisitos previos

  • Node.js 18 o más reciente
  • Una cuenta de Scrapeless y una clave API — regístrate en app.scrapeless.com
  • Playwright instalado (npm install playwright)
  • Familiaridad básica con npm y variables de entorno de Node.js

Instalar

1. Agrega Playwright a tu proyecto

Si aún no tienes Playwright, instálalo:

bash Copy
npm install playwright

Esto descarga la biblioteca de Playwright para los tres motores de navegador.

2. Establece tu clave API de Scrapeless

Guarda la clave como una variable de entorno para que nunca se incluya en el control de versiones:

bash Copy
export SCRAPELESS_API_KEY="tu_clave_api_aquí"

3. No se requiere SDK adicional

Playwright se conecta al Scrapeless Scraping Browser a través del Protocolo de DevTools de Chrome, por lo que no hay ningún paquete adicional que instalar más allá de Playwright mismo.


Configura el proxy integrado de Playwright

Playwright acepta configuraciones de proxy en launch() y en newContext(). Apunta server a tu puerta de enlace proxy y pasa las credenciales:

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

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://tu-host-proxy:8080', // tu puerta de enlace proxy
      username: 'tu-usuario-proxy',
      password: 'tu-contraseña-proxy',
    },
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());

  await browser.close();
})();

Esa es toda la superficie a nivel de biblioteca, y funciona igual en Chromium, Firefox y WebKit. Dos cosas que no hace: asume que ya tienes un conjunto de direcciones residenciales para apuntar server, y deja la huella digital de automatización del navegador intacta. La configuración de proxy en crudo mueve tu tráfico a una nueva IP; no cambia cómo la página lee el cliente.

Obtén tu clave API en el plan gratuito: app.scrapeless.com


Dónde se detiene la configuración de proxy en crudo — huellas digitales y fuentes de IP

Dos huecos se encuentran entre launch({ proxy }) y una ejecución de automatización que los sitios públicos sirven de manera limpia: obtener y rotar una verdadera red residencial, y la huella digital que el navegador presenta una vez que llega. El Navegador de Scraping Sin Raspado cierra ambos. Es un navegador en la nube anti-detección construido para rastreadores web y agentes de IA, y como habla el Protocolo de Herramientas de Desarrollo de Chrome, Playwright se conecta a él con una línea. Para Playwright específicamente, ofrece:

  • Nodos de salida residenciales en más de 195 países, con la huella de automatización manejada en la nube.
  • Renderizado de JavaScript en la nube — el navegador remoto ejecuta la página, así que el trabajo sale de tu máquina.
  • Geo-apuntado y sesiones persistentes como parámetros de conexiónproxyCountry, sessionName, y sessionTTL se integran en la cadena de punto final.
  • Sin límite de asiento concurrente — paga por uso y abre tantas sesiones como necesite la ejecución.

La cadena de conexión lleva tu clave como el parámetro token; la documentación en docs.scrapeless.com lista todas las opciones. Obtén tu clave de API en el plan gratuito en app.scrapeless.com.

Conectar Playwright a través de CDP

Construye el punto final de WebSocket, luego conéctate con chromium.connectOverCDP(). Desde ahí es Playwright ordinario: el proxy y la huelle digital ya están aplicados en el navegador remoto:

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

const token = process.env.SCRAPELESS_API_KEY;
const params = new URLSearchParams({
  token,
  proxyCountry: 'US',  // fijar la región de salida residencial
  sessionTTL: '300',   // mantener la sesión viva durante 300 segundos
});
const wsEndpoint = `wss://browser.scrapeless.com/api/v2/browser?${params.toString()}`;

(async () => {
  const browser = await chromium.connectOverCDP(wsEndpoint);
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
  console.log('Título:', await page.title());

  // Confirmar que la salida es una IP residencial, no la de la máquina anfitriona
  const ipPage = await context.newPage();
  await ipPage.goto('https://api.ipify.org?format=json', { waitUntil: 'domcontentloaded' });
  console.log('Salida:', await ipPage.evaluate(() => document.body.innerText));

  await browser.close();
})();

Fijar un país y reutilizar una IP

El geo-apuntado es el parámetro proxyCountry. La persistencia es sessionName más un sessionTTL vivo: reutiliza el mismo nombre dentro de la ventana y cada navegación sale de la misma IP residencial, que es lo que mantiene un flujo de inicio de sesión en una identidad.

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

const token = process.env.SCRAPELESS_API_KEY;

function endpoint({ country, session }) {
  const params = new URLSearchParams({
    token,
    proxyCountry: country,
    sessionName: session,  // mismo nombre + TTL vivo = misma IP de salida
    sessionTTL: '300',
  });
  return `wss://browser.scrapeless.com/api/v2/browser?${params.toString()}`;
}

(async () => {
  const browser = await chromium.connectOverCDP(endpoint({ country: 'US', session: 'demo-session' }));
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto('https://api.ipify.org?format=json', { waitUntil: 'domcontentloaded' });
  console.log('Primero :', await page.evaluate(() => document.body.innerText));

  await page.goto('https://api.ipify.org?format=json', { waitUntil: 'domcontentloaded' });
  console.log('Segundo:', await page.evaluate(() => document.body.innerText));

  await browser.close();
})();

Ejecutar sesiones en paralelo

Cada conexión es independiente, por lo que un grupo de trabajadores es Promise.all sobre varios puntos finales con nombres de sesión distintos. Mantén la concurrencia a tres por anfitrión para ser educado:

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

const token = process.env.SCRAPELESS_API_KEY;

function endpoint(session) {
  const params = new URLSearchParams({ token, proxyCountry: 'US', sessionName: session, sessionTTL: '180' });
  return `wss://browser.scrapeless.com/api/v2/browser?${params.toString()}`;
}

async function fetchIp(session) {
  const browser = await chromium.connectOverCDP(endpoint(session));
  try {
    const page = await browser.newContext().then(c => c.newPage());
    await page.goto('https://api.ipify.org?format=json', { waitUntil: 'domcontentloaded' });
    return { session, ip: JSON.parse(await page.evaluate(() => document.body.innerText)).ip };
  } finally {
    await browser.close();
  }
}

(async () => {
  const workers = ['worker-1', 'worker-2', 'worker-3'];
javascript Copy
const resultados = await Promise.all(trabajadores.map(obtenerIp));
  console.log(resultados);
})();

Lo que obtienes de vuelta

Cada sesión informa de una salida residencial distinta, y una sesión persistente informa la misma dos veces. La ejecución paralela anterior devuelve un registro por trabajador:

javascript Copy
// Muestra ilustrativa — el esquema es exacto; el valor de IP es ilustrativo y varía por sesión.
[
  { "sesión": "trabajador-1", "ip": "72.188.194.89" },
  { "sesión": "trabajador-2", "ip": "172.56.218.152" },
  { "sesión": "trabajador-3", "ip": "73.135.52.138" }
]

Notas sobre el esquema:

  • proxyCountry: 'US' asigna cada salida a una dirección residencial en EE. UU.; cambia el código para dirigir a otra región.
  • Dentro de un sessionName y un sessionTTL activo, la IP permanece constante a través de las navegaciones; un nuevo nombre obtiene una dirección nueva.
  • Los selectores deben coincidir con el marcado actual del sitio objetivo — ajusta los selectores cuando el DOM cambie.
  • El navegador remoto renderiza JavaScript por defecto, por lo que el contenido del lado del cliente está presente antes de que leas el DOM.

Solución de problemas

La conexión se interrumpe a mitad de una ejecución larga

Causa: sessionTTL expiró antes de que el flujo de trabajo terminara.

Solución: Establece sessionTTL para cubrir todo el flujo desde el principio; es la duración de la sesión en segundos, así que ajústalo al encadenamiento de navegación más largo que esperas.

El sitio aún muestra una página de "Acceso Denegado"

Causa: Una IP residencial limpia no es la única señal; una sesión fría que salta directamente a una URL profunda aún parece automatizada.

Solución: Calienta la sesión cargando primero la página de inicio del sitio en el mismo contexto, fija proxyCountry a una región que coincida con la audiencia y proporciona opciones realistas en el contexto (userAgent, Accept-Language).

La extracción devuelve campos vacíos

Causa: Los selectores ya no coinciden con el marcado renderizado.

Solución: Vuelve a inspeccionar la página y ajusta los selectores; protege los campos opcionales para que un elemento perdido devuelva null en lugar de lanzar una excepción.


Conclusión: una capa proxy que se mantiene fuera de tu código de aplicación

Una ejecución de Playwright con proxy se reduce a unos pocos movimientos: construye el punto final, conéctate a través de CDP, fija el país y escribe el mismo Playwright que ya conoces. launch({ proxy }) cubre el caso en el que eres dueño del pool; el Navegador de Scraping cubre los casos en los que necesitas salidas residenciales reales y una huella digital que se mantenga. Fija la salida con proxyCountry, mantén una identidad con sessionName más un sessionTTL activo, limita la concurrencia a tres por host y trata los campos ausentes como anulables. Para una visión más amplia sobre estrategias de rotación, consulta best-rotating-proxies-2026.


¿Listo para automatizar a gran escala con Playwright y proxies?

Únete a nuestra comunidad para reclamar un plan gratuito y conectarte con desarrolladores que construyen automatización con Playwright: Discord · Telegram.

Regístrate en app.scrapeless.com para disfrutar de tiempo de ejecución gratuito del Navegador de Scraping, revisa precios y adapta los patrones anteriores a las regiones y sitios que tu automatización necesita.


Preguntas Frecuentes

Raspar datos públicamente visibles está amplísimamente permitido, pero las reglas varían según la jurisdicción y los términos de servicio de un sitio. Revisa los términos del objetivo, evita datos detrás de un inicio de sesión que no estás autorizado a usar y consulta con un abogado para cualquier cosa sensible.

P: ¿Necesito un proxy?

Lo necesitas siempre que el objetivo bloquee IPs de centros de datos o aplique restricciones geográficas, lo que cubre la mayoría de los sitios públicos a gran escala. Una salida residencial permite que la solicitud llegue como tráfico común de usuario; sin ella, una IP en la nube es un bloque fácil.

P: Recibo una página de "Acceso Denegado" — ¿cómo obtengo una representación limpia?

Carga primero la página de inicio del sitio en el mismo contexto para calentar la sesión, fija proxyCountry a una región que se ajuste a la audiencia y establece opciones de contexto realistas como userAgent y Accept-Language. Un acceso a una URL profunda desde un contexto frío es el desencadenante habitual.

P: ¿Puedo ejecutar muchas sesiones de Playwright a la vez?

Sí. Cada conexión CDP es independiente y extrae su propia IP residencial, por lo que un grupo de trabajadores es Promise.all sobre varios puntos finales con distintos valores de sessionName. Mantén la concurrencia a tres por host para que te mantengas dentro de límites corteses.

P: ¿Cómo cambio el país de salida?

Cambia el parámetro proxyCountry y abre una nueva conexión. El país se fija cuando se crea la sesión, así que una región diferente significa una nueva cadena de punto final en lugar de un cambio a mitad de sesión.

P: ¿Esto funciona en sitios con mucho JavaScript?

Sí. El navegador remoto ejecuta la página antes de que la leas, por lo que el contenido renderizado en el cliente ya está en el DOM para cuando page.goto() se resuelve. Usa waitUntil: 'domcontentloaded' más un corto período de asentamiento en los sitios cuya red nunca se inactiva.

P: ¿Qué sucede cuando el marcado del sitio cambia?

Los selectores vinculados a una clase o estructura específica se rompen cuando un sitio lanza un rediseño. Extracción de anclas en la señal más estable disponible: un atributo de datos o un patrón de URL duradero sobre una clase CSS hasheada, y vuelve a verificar los selectores cuando los campos comienzan a regresar vacíos.

En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.

Artículos más populares

Catalogar