Browser Use con proxy: cómo configurar el agente de IA

Publicado:

16 min de lectura

Acar Diveroli
Autor: Acar Diveroli
Filas tenues de IP tras un marco con cruces en las esquinas: logo de Proxynet, una x fina, logo de Browser Use, INTEGRATION

En tu equipo, tu agente de Browser Use hace sin problemas un pedido de prueba en la tienda de tu entorno de pruebas (staging). En un servidor en la nube, la misma tarea abre el sitio desde una dirección de centro de datos en otro país: la tienda muestra otra moneda, y el firewall de tu entorno de pruebas, que solo deja entrar IP conocidas, rechaza al agente. Añades un proxy como http://user:pass@pr.proxynet.io:8000 y, a partir de ese momento, todas las páginas fallan con net::ERR_NO_SUPPORTED_PROXIES.

Esta guía explica cómo funciona Browser Use, la instalación, un proxy con usuario y contraseña, la comprobación de la IP de salida, las sesiones fijas y rotativas, los límites de dominio, los secretos y un paso de aprobación humana. Probamos todos los scripts con browser-use 0.13.10 y Python 3.13 a través de un proxy de prueba local que pide contraseña. Como no había ninguna clave de API de un LLM en el equipo de prueba, un script escrito de antemano dio las respuestas del modelo; el navegador, el proxy, el filtro de dominios y el enmascaramiento de secretos sí funcionaron de verdad.

¿Qué es Browser Use?

Browser Use es una biblioteca de Python que convierte un modelo de lenguaje en un agente de navegador. Describes la tarea con palabras sencillas, y el modelo decide los clics, lo que se escribe y el desplazamiento por la página. El repositorio de GitHub lo describe como «Agents that use the browser» (agentes que usan el navegador); tiene licencia MIT, y la última versión en PyPI es hoy la 0.13.10, publicada el 4 de septiembre de 2026, para Python 3.11 o posterior.

La versión 0.13.10 se comunica con Chromium directamente mediante el Chrome DevTools Protocol (CDP); Playwright no figura entre sus dependencias. El modelo puede venir de OpenAI, Anthropic, Google, un servidor local de Ollama o los modelos alojados del propio Browser Use. Browser Use Cloud, un servicio de pago aparte con navegadores alojados, no forma parte de esta guía.

Cómo planifica un agente y cómo usa herramientas en general se explica en Agentes de IA: planificación, herramientas y memoria; los navegadores con un agente integrado, en ¿Qué es un navegador con IA?.

¿Cómo funciona un agente de Browser Use?

Una ejecución de agent.run() pasa por estos pasos:

  1. El navegador arranca con un perfil temporal nuevo. El proxy se pasa a Chromium como parámetro de inicio.
  2. Una URL incluida en la tarea se abre directamente, sin llamar al modelo.
  3. La página se convierte en texto. Cada elemento que el agente puede usar recibe un número, acompañado del texto visible. Con use_vision=True (el valor predeterminado) se añade una captura de pantalla.
  4. El modelo responde en JSON: una evaluación del último paso, una memoria breve, el siguiente objetivo y hasta cinco acciones, como navigate, click, input, scroll, extract o done.
  5. La biblioteca ejecuta las acciones, comprueba cada URL nueva con tus reglas de dominio y rellena los secretos donde el modelo escribió un marcador de posición.
  6. El ciclo se repite hasta que el modelo llama a done o se agota max_steps.

En una librería de práctica, el estado del navegador que recibió nuestro modelo de prueba contenía líneas como estas:

text
[587]<a title=It's Only the Himalayas />
	It's Only the Himalayas
£45.17
[597]<i />
In stock
[604]<button type=submit />
	Add to basket

Para añadir este libro a la cesta, el modelo respondería {"click": {"index": 604}}. Como la página llega en forma de texto, use_vision=False también funciona y evita que las capturas de páginas sensibles lleguen al proveedor del modelo.

¿Cómo se instala Browser Use?

La guía de inicio rápido oficial usa uv:

bash
pip install uv
uv venv --python 3.12
source .venv/bin/activate        # Windows: .venv\Scripts\activate
uv pip install browser-use
uvx browser-use install          # descarga Chromium

Nosotros instalamos con un simple pip install browser-use==0.13.10 en un entorno virtual de Python 3.13, y también funcionó. Después, pon las claves en un archivo .env junto a tu script:

bash
OPENAI_API_KEY=...
PROXY_SERVER=http://pr.proxynet.io:8000
PROXY_USERNAME=user
PROXY_PASSWORD=pass
ANONYMIZED_TELEMETRY=false

La última línea importa. Browser Use envía telemetría de uso de forma predeterminada, y su página de telemetría indica que puede incluir las instrucciones de la tarea, las URL visitadas, el registro de acciones y los resultados finales. Si tus tareas mencionan clientes o sitios internos, desactívala.

Dos cosas nos sorprendieron en el equipo de prueba con Windows. Sin executable_path, Browser Use eligió el Google Chrome instalado, aunque con un perfil temporal nuevo y no con el de uso diario. En el primer arranque también descargó tres extensiones, entre ellas un bloqueador de anuncios, directamente de Chrome Web Store y por fuera del proxy; enable_default_extensions=False las desactiva.

¿Cómo se ejecuta un agente a través de un proxy?

El proxy es un ajuste del Browser, y el agente recibe ese navegador. Este script abre una página de categoría y lee tres libros, saliendo solo por el proxy y solo hacia un dominio:

python
"""Ejecuta un agente de Browser Use a través de un proxy autenticado, limitado a un solo sitio."""
import asyncio
import os

from dotenv import load_dotenv

load_dotenv()  # lee OPENAI_API_KEY, PROXY_* y ANONYMIZED_TELEMETRY de .env

from browser_use import Agent, Browser, ChatOpenAI
from browser_use.browser import ProxySettings

browser = Browser(
    headless=True,
    proxy=ProxySettings(
        server=os.environ["PROXY_SERVER"],  # http://pr.proxynet.io:8000
        username=os.environ["PROXY_USERNAME"],
        password=os.environ["PROXY_PASSWORD"],
    ),
    allowed_domains=["books.toscrape.com"],
    enable_default_extensions=False,
)

agent = Agent(
    task=(
        "Abre https://books.toscrape.com/catalogue/category/books/travel_2/index.html "
        "y enumera el título y el precio de los tres primeros libros."
    ),
    llm=ChatOpenAI(model="gpt-4.1-mini"),
    browser=browser,
    use_vision=False,
)


async def main():
    history = await agent.run(max_steps=10)
    print("result:", history.final_result())
    print("pages: ", [u for u in history.urls() if u])
    print("steps: ", history.number_of_steps())


asyncio.run(main())

ProxySettings se importa desde browser_use.browser, no desde el paquete principal. La página de parámetros del navegador enumera cuatro campos:

CampoQué recibe
serverhttp://host:port o socks5://host:port, sin credenciales
usernameUsuario del proxy, por ejemplo el que da el Generador de endpoints
passwordContraseña del proxy
bypassHosts que no pasan por el proxy, separados por comas

Internamente, Browser Use inicia Chromium con --proxy-server y responde él mismo al desafío 407 del proxy mediante CDP. Nuestro proxy de prueba registró exactamente eso para la página del libro (abreviado, sin marcas de tiempo):

text
407 CONNECT books.toscrape.com:443 (no credentials)
200 CONNECT books.toscrape.com:443 user=user

El usuario y la contraseña del proxy no aparecieron en nada de lo que recibió el modelo.

¿Por qué falla user:pass en la URL del proxy?

Porque Chromium ignora las credenciales escritas dentro de su ajuste de proxy. Según la documentación de proxies de Chromium, Chrome no usa ninguna credencial incrustada en la configuración del proxy. Con server="http://user:pass@…" y sin campos aparte, cada navegación de nuestra prueba terminó con net::ERR_NO_SUPPORTED_PROXIES. Pon las credenciales en username y password.

SOCKS5 tiene otro límite: Chromium no admite ningún método de autenticación para SOCKS5. Nuestro servidor SOCKS5 de prueba vio que el navegador solo ofrecía «no authentication» (sin autenticación), y la página falló con ERR_SOCKS_CONNECTION_FAILED. Para SOCKS5, añade la IP de tu servidor a la lista de IP autorizadas del panel (hasta 10 direcciones) y usa, sin usuario, el puerto SOCKS5 que muestra el Generador de endpoints. Así el DNS se resuelve del lado del proxy. Los dos métodos de acceso se comparan en Autenticación de proxy: user:pass o lista blanca de IP, y los protocolos, en Diferencia entre SOCKS y HTTP.

¿Cómo se comprueba la IP de salida del agente?

Compruébala antes de la primera tarea real, sin ningún modelo en el ciclo. Este script usa los mismos ProxySettings, abre una página que devuelve la IP del visitante e imprime lo que vio el sitio:

python
"""Abre una página de eco de IP a través del proxy antes de ejecutar cualquier agente."""
import asyncio
import os

from browser_use import Browser
from browser_use.browser import ProxySettings


async def main():
    browser = Browser(
        headless=True,
        proxy=ProxySettings(
            server=os.environ["PROXY_SERVER"],
            username=os.environ["PROXY_USERNAME"],
            password=os.environ["PROXY_PASSWORD"],
        ),
    )
    await browser.start()
    try:
        page = await browser.new_page("https://httpbin.org/ip")
        await asyncio.sleep(2)  # deja que la página cargue
        print(await page.evaluate("() => document.body.innerText"))
    finally:
        await browser.kill()


asyncio.run(main())

Imprime el JSON de httpbin con un campo origin. A través de un endpoint de Proxynet, esa es la IP de salida, no la tuya. Ejecútalo dos veces: un usuario rotativo puede mostrar dos direcciones distintas, y uno de sesión fija, la misma dirección las dos veces.

El registro de nuestro proxy también mostró las peticiones propias de Chrome a servicios de Google y la carga del logotipo de Browser Use en la página de inicio en blanco; si pagas el tráfico del proxy por GB, también cuentan.

Rotativa o fija: ¿qué sesión necesita un agente?

El proxy pertenece al navegador, así que cada paso de una tarea sale por la misma dirección de proxy. Lo que cambia es la IP de salida detrás de esa dirección.

TareaSesiónPor qué
Iniciar sesión y luego actuar en varias páginasFija, 10-30 minutosMuchos sitios vinculan la sesión a una IP; una dirección nueva a mitad de la tarea puede obligar a iniciar sesión otra vez
Leer una página independiente en cada ejecuciónRotativaCada ejecución puede recibir una salida nueva; nada pasa de una a otra
Varios agentes en paraleloUn Browser por agenteCada navegador tiene su propia configuración de proxy y su propia sesión
Una dirección que tus propios sistemas tienen en una lista de permitidosISP estáticoLa IP se mantiene igual durante días

En Proxynet eliges sesión rotativa o fija, país y ciudad en el Generador de endpoints, con una duración de sesión fija de 1 a 60 minutos; el usuario que genera ya incluye esas opciones, así que pégalo tal cual en PROXY_USERNAME. Elige una duración un poco mayor que tu tarea más larga. Productos: Proxies de sesión fija, Proxies rotativos, Proxies ISP y, cuando una comprobación necesita una conexión doméstica en un país concreto, Proxies residenciales. Cómo funciona la rotación se explica en Qué es la rotación de IP y cómo funciona.

¿Cómo se limita adónde puede ir el agente?

allowed_domains recibe una lista de patrones: example.com, *.example.com para subdominios y http*://example.com para ambos esquemas. Los comodines en el dominio de nivel superior se rechazan. prohibited_domains funciona al revés; si se definen los dos, gana la lista de permitidos.

Permitimos solo nuestra tienda local e hicimos que el modelo de prueba intentara salir por dos vías. Un navigate directo a otro host le devolvió esto al modelo, con about:blank como página actual:

text
Navigation failed: Navigation to http://partner.test:28140/ blocked by security policy

Un enlace de la tienda que redirigía a ese mismo host también terminó en about:blank, y el modelo nunca vio el texto de esa página. Pero el registro del propio sitio de prueba mostró que el navegador había solicitado ambas páginas fuera de la lista antes de que la comprobación las reemplazara, y una imagen del host no permitido se cargó con normalidad dentro de una página permitida. En la 0.13.10, el filtro controla lo que el agente lee y sobre lo que actúa, no lo que envía el navegador.

Para un límite real, restringe el tráfico saliente fuera del agente: un firewall o una lista de permitidos en el lado del proxy, un contenedor o una cuenta de usuario aparte, y ningún acceso a direcciones internas. Playwright MCP tiene la misma salvedad con sus flags de origen, como se explica en Qué es Playwright MCP. El patrón general está en Acceso web seguro para LLM.

¿Cómo se mantienen las credenciales lejos del modelo?

Nunca escribas una contraseña en la tarea. La tarea va al proveedor del modelo en cada paso y, salvo que la desactives, a la telemetría. Browser Use tiene un mecanismo de marcadores de posición para esto, sensitive_data: pasas los valores reales en el código, el modelo solo ve nombres como x_user y x_pass, y la biblioteca escribe el valor real en el campo después de que el modelo responde.

En nuestra prueba, la acción del modelo fue <secret>x_pass</secret>, el registro mostró «Typed <sensitive>» y, cuando la página repitió el nombre de usuario, el modelo recibió Signed in as <secret>x_user</secret>. Los valores reales no aparecieron en ninguna entrada del modelo. Tres hábitos completan la protección:

  • Asocia los secretos a un dominio, para que un marcador solo se rellene en el sitio al que pertenece.
  • Usa use_vision=False en las páginas donde una captura podría mostrar el valor.
  • No le des al agente tu perfil de Chrome de uso diario (Browser.from_system_chrome()) para tareas que leen páginas externas: cualquier sesión iniciada en él queda a su alcance.

¿Cómo se añade un paso de aprobación humana?

La inyección de prompts indirecta es un texto de una página que el modelo toma como instrucción. La entrada LLM01 de OWASP incluye la aprobación humana para acciones de alto riesgo entre las defensas. Browser Use llama a register_new_step_callback después de que el modelo elige sus acciones y antes de ejecutarlas, así que el callback puede detener al agente:

python
"""Agente de Browser Use con lista de permitidos, marcadores para secretos y aprobación humana."""
import asyncio
import os

from dotenv import load_dotenv

load_dotenv()

from browser_use import Agent, Browser, ChatOpenAI
from browser_use.browser import ProxySettings

SITE = "https://shop.example.com"
READ_ONLY = {"navigate", "scroll", "find_text", "extract", "screenshot", "go_back", "wait", "done"}

browser = Browser(
    headless=True,
    proxy=ProxySettings(
        server=os.environ["PROXY_SERVER"],
        username=os.environ["PROXY_USERNAME"],
        password=os.environ["PROXY_PASSWORD"],
    ),
    allowed_domains=["shop.example.com"],
    enable_default_extensions=False,
)


def approve(browser_state, model_output, step):
    """Se ejecuta después de que el modelo elige sus acciones y antes de que se ejecuten."""
    planned = [action.model_dump(exclude_none=True) for action in model_output.action]
    if all(next(iter(a)) in READ_ONLY for a in planned):
        return
    print(f"Step {step} wants to run: {planned}")
    if input("Allow? [y/N] ").strip().lower() != "y":
        agent.stop()


agent = Agent(
    task=f"Inicia sesión en {SITE}/login con el usuario x_user y la contraseña x_pass y luego abre la oferta del socio.",
    llm=ChatOpenAI(model="gpt-4.1-mini"),
    browser=browser,
    sensitive_data={"http*://shop.example.com": {"x_user": os.environ["SHOP_USER"], "x_pass": os.environ["SHOP_PASS"]}},
    use_vision=False,
    register_new_step_callback=approve,
)


async def main():
    history = await agent.run(max_steps=8)
    print("done:  ", history.is_done())
    print("errors:", [e for e in history.errors() if e])


asyncio.run(main())

Lo ejecutamos contra nuestra tienda local, con el dominio cambiado. El paso de inicio de sesión pidió confirmación primero; tras «y», el agente escribió ambos valores e hizo clic. Un clic posterior volvió a preguntar y, tras «n», el registro mostró «Agent stopping», el clic no se ejecutó y la llamada is_done() devolvió False. Cualquier acción fuera del conjunto de solo lectura, incluida la escritura de texto, ahora espera a una persona.

¿Browser Use o Playwright MCP?

Ambos permiten que un modelo use un navegador; se diferencian en quién ejecuta el ciclo.

Browser UsePlaywright MCP
Quién ejecuta el ciclo del agenteLa biblioteca, en tu código PythonEl asistente que ya usas (Claude Code, Cursor)
Proxy con contraseñaCampos de ProxySettingslaunchOptions.proxy en un archivo de configuración
Límite de dominiosallowed_domains--allowed-origins
Adecuado paraAgentes dentro de tu propio servicioTrabajo puntual desde un asistente de programación

La instalación y los flags de Playwright MCP están en Qué es Playwright MCP.

Casos de uso

  • Comprobaciones de localización en tu propio sitio: qué idioma, moneda y aviso de cookies recibe un visitante de un país concreto (pruebas de localización).
  • Pruebas exploratorias de tu propia aplicación: recorrer un flujo de registro o de pago en el entorno de pruebas desde distintas ubicaciones (pruebas de aplicaciones).
  • Lecturas puntuales de una página con JavaScript: algunos valores de una página pública que se renderiza en el navegador (páginas estáticas y dinámicas). Para trabajos periódicos, un script normal sale más barato (Playwright con un proxy).
  • Texto limpio para un modelo en lugar de un navegador: si el agente solo necesita leer, consulta Qué es Crawl4AI.

Un agente que navega por ti sigue generando tráfico automatizado. Browser Use 0.13.10 no lee robots.txt (no encontramos código para ello en el paquete), así que lee tú mismo el robots.txt y las condiciones del sitio, usa una API oficial cuando exista, limítate a unas pocas páginas a ritmo humano y detente cuando un sitio diga que no. Por qué los sitios distinguen a los visitantes automatizados se explica en ¿Por qué los sitios bloquean a los agentes de compra con IA?. Las funciones stealth y de CAPTCHA que se anuncian para Browser Use Cloud quedan fuera de esta guía, y no las recomendamos.

Errores comunes

Lo que vesPor quéQué hacer
net::ERR_NO_SUPPORTED_PROXIESCredenciales escritas en serverPásalas a username y password
net::ERR_TOO_MANY_RETRIESUsuario o contraseña del proxy incorrectos; el proxy sigue respondiendo 407Vuelve a copiar las credenciales desde el panel
net::ERR_PROXY_CONNECTION_FAILEDHost o puerto incorrectos, o tráfico saliente bloqueadoPrueba la misma dirección con cURL
ERR_SOCKS_CONNECTION_FAILEDsocks5:// con contraseñaUsa el endpoint HTTP, o SOCKS5 con lista de IP autorizadas
blocked by security policyLa URL está fuera de allowed_domainsAñade el dominio o déjalo bloqueado
El agente vuelve a iniciar sesión a mitad de la tareaUna salida rotativa cambió la IP durante la tareaUsa una sesión fija

Dos hábitos causan problemas sin mostrar ningún error: tratar allowed_domains como un firewall y usar una versión sin fijar. La API ha cambiado entre versiones, así que fija la que probaste (browser-use==0.13.10) y lee las notas de la versión antes de actualizar.

Guía de decisión

NecesidadRecomendación
Una primera ejecución del agente a través de un proxyProxySettings con el endpoint HTTP, usuario y contraseña; después, el script de eco de IP
Una tarea de varios pasos con inicio de sesiónSesión fija más larga que la tarea
Ejecuciones independientes de una sola páginaSesión rotativa
Mantener al agente en un solo sitioallowed_domains, más una lista de permitidos para el tráfico saliente fuera del agente
Acciones que cambian algoUn callback de aprobación que pueda llamar a agent.stop()

Preguntas frecuentes

¿Browser Use es gratis?

La biblioteca es gratuita con licencia MIT. Pagas las llamadas al modelo, al menos una por paso, y el tráfico del proxy. Browser Use Cloud y sus modelos alojados se facturan aparte.

¿Browser Use sigue usando Playwright?

No para manejar el navegador. La versión 0.13.10 controla Chromium mediante el Chrome DevTools Protocol; el comando de instalación usa el descargador de Playwright para obtener Chromium, y el estado de sesión guardado usa el formato de archivo de Playwright.

¿Puedo usar un modelo local en lugar de una API?

La página de modelos compatibles muestra ChatOllama(model="llama3.1:8b") para un servidor local de Ollama. No probamos ningún modelo local.

¿Pueden dos agentes usar países distintos al mismo tiempo?

Sí, con dos objetos Browser, cada uno con sus propios ProxySettings. Un navegador tiene un solo proxy para todas sus pestañas.

¿Browser Use respeta robots.txt?

No por sí solo; la versión 0.13.10 no comprueba robots.txt. Lee el archivo antes de darle un sitio al agente.

¿Un proxy evita que los sitios bloqueen a mi agente?

No. Un proxy cambia la dirección desde la que sale una petición; el comportamiento del navegador y el ritmo siguen igual. Un ritmo lento, las páginas permitidas y la API oficial son el camino duradero.

En resumen

Browser Use le da a un modelo de lenguaje un navegador Chromium real y ejecuta el ciclo del agente en tu propio código Python. Configura el proxy en el navegador con ProxySettings y los campos username y password por separado; tanto las credenciales en la URL como SOCKS5 con contraseña fallan en Chromium. Comprueba la IP de salida antes de la primera tarea, usa una sesión fija para todo lo que tenga inicio de sesión y trata allowed_domains como un filtro para el agente, no como un límite de red. Guarda los secretos en sensitive_data, desactiva la telemetría y haz que una persona apruebe las acciones que cambian algo. Tienes salidas adecuadas para tu agente en nuestros servicios de proxy.