mirror of
https://github.com/browser-use/browser-use
synced 2026-05-06 17:52:15 +02:00
416 lines
15 KiB
Plaintext
416 lines
15 KiB
Plaintext
---
|
|
title: "Connect to your Browser"
|
|
description: "Connect to a remote browser or launch a new local browser."
|
|
icon: "computer"
|
|
---
|
|
|
|
## Overview
|
|
|
|
Browser Use supports a wide variety of ways to launch or connect to a browser:
|
|
|
|
- Launch a new local browser using playwright/patchright chromium (the default)
|
|
- Connect to a remote browser using CDP or WSS
|
|
- Use an existing playwright `Page`, `Browser`, or `BrowserContext` object
|
|
- Connect to a local browser already running using `browser_pid`
|
|
|
|
<Tip>
|
|
Don't want to manage your own browser infrastructure? Try [☁️ Browser Use Cloud](https://browser-use.com) ➡️
|
|
|
|
We provide automatic CAPTCHA solving, proxies, human-in-the-loop automation, and more!
|
|
</Tip>
|
|
|
|
## Connection Methods
|
|
|
|
### Method A: Launch a New Local Browser (Default)
|
|
|
|
Launch a local browser using built-in default (playwright `chromium`) or a provided `executable_path`:
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
|
|
# If no executable_path provided, uses Playwright/Patchright's built-in Chromium
|
|
browser_session = BrowserSession(
|
|
# Path to a specific Chromium-based executable (optional)
|
|
executable_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', # macOS
|
|
# For Windows: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
|
|
# For Linux: '/usr/bin/google-chrome'
|
|
|
|
# Use a specific data directory on disk (optional, set to None for incognito)
|
|
user_data_dir='~/.config/browseruse/profiles/default', # this is the default
|
|
# ... any other BrowserProfile or playwright launch_persistnet_context config...
|
|
# headless=False,
|
|
)
|
|
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
browser_session=browser_session,
|
|
)
|
|
```
|
|
|
|
We support most `chromium`-based browsers in `executable_path`, including [Brave](https://github.com/browser-use/browser-use/tree/main/examples/browser/stealth.py), [patchright chromium](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright), [rebrowser](https://rebrowser.net/), Edge, and more. See [`examples/browser/stealth.py`](https://github.com/browser-use/browser-use/tree/main/examples/browser) for more. We do not support Firefox or Safari at the moment.
|
|
|
|
<Warning>
|
|
[As of Chrome v136](https://github.com/browser-use/browser-use/issues/1520), driving browsers with the default profile is [no longer supported](https://developer.chrome.com/blog/remote-debugging-port) for security reasons. Browser-Use has transitioned to creating a new dedicated profile for agents in: `~/.config/browseruse/profiles/default`. You can [open this profile](https://superuser.com/questions/377186/how-do-i-start-chrome-using-a-specified-user-profile) and log into everything you need your agent to have access to, and it will persist over time.
|
|
</Warning>
|
|
|
|
### Method B: Connect Using Existing Playwright Objects
|
|
|
|
Pass existing Playwright `Page`, `BrowserContext`, `Browser`, and/or `playwright` API object to `BrowserSession(...)`:
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
from playwright.async_api import async_playwright
|
|
# from patchright.async_api import async_playwright # stealth alternative
|
|
|
|
async with async_playwright() as playwright:
|
|
browser = await playwright.chromium.launch()
|
|
context = await browser.new_context()
|
|
page = await context.new_page()
|
|
|
|
browser_session = BrowserSession(
|
|
page=page,
|
|
# browser_context=context, # all these are supported
|
|
# browser=browser,
|
|
# playwright=playwright,
|
|
)
|
|
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
browser_session=browser_session,
|
|
)
|
|
```
|
|
|
|
You can also pass `page` directly to `Agent(...)` as a shortcut.
|
|
|
|
```python
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
page=page,
|
|
)
|
|
```
|
|
|
|
### Method C: Connect to Local Browser Using Browser PID
|
|
|
|
Connect to a browser with open `--remote-debugging-port`:
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
|
|
# First, start Chrome with remote debugging:
|
|
# /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --remote-debugging-port=9242
|
|
|
|
# Then connect using the process ID
|
|
browser_session = BrowserSession(browser_pid=12345) # Replace with actual Chrome PID
|
|
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
browser_session=browser_session,
|
|
)
|
|
```
|
|
|
|
### Method D: Connect to remote Playwright Node.js Browser Server via WSS URL
|
|
|
|
Connect to Playwright Node.js server providers:
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
|
|
# Connect to a playwright server
|
|
browser_session = BrowserSession(wss_url="wss://your-playwright-server.com/ws")
|
|
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
browser_session=browser_session,
|
|
)
|
|
```
|
|
|
|
### Method E: Connect to Remote Browser via CDP URL
|
|
|
|
Connect to any remote Chromium-based browser:
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
|
|
# Connect to Chrome via CDP
|
|
browser_session = BrowserSession(cdp_url="http://localhost:9222")
|
|
|
|
agent = Agent(
|
|
task="Your task here",
|
|
llm=llm,
|
|
browser_session=browser_session,
|
|
)
|
|
```
|
|
|
|
|
|
|
|
## Security Considerations
|
|
|
|
<Warning>
|
|
When using any browser profile, the agent will have access to:
|
|
- All its logged-in sessions and cookies
|
|
- Saved passwords (if autofill is enabled)
|
|
- Browser history and bookmarks
|
|
- Extensions and their data
|
|
|
|
Always review the task you're giving to the agent and ensure it aligns with your security requirements!
|
|
Use `Agent(sensitive_data={'https://auth.example.com': {x_key: value}})` for any secrets, and restrict the browser with `BrowserSession(allowed_domains=['https://*.example.com'])`.
|
|
</Warning>
|
|
|
|
## Best Practices
|
|
|
|
1. **Use isolated profiles**: Create separate Chrome profiles for different agents to limit scope of risk:
|
|
```python
|
|
browser_session = BrowserSession(
|
|
user_data_dir='~/.config/browseruse/profiles/banking',
|
|
# profile_directory='Default'
|
|
)
|
|
```
|
|
|
|
2. **Limit domain access**: Restrict which sites the agent can visit:
|
|
```python
|
|
browser_session = BrowserSession(
|
|
allowed_domains=['example.com', 'http*://*.github.com'],
|
|
)
|
|
```
|
|
|
|
3. **Enable `keep_alive=True`** If you want to use a single `BrowserSession` with more than one agent:
|
|
```python
|
|
browser_session = BrowserSession(
|
|
keep_alive=True,
|
|
...
|
|
)
|
|
await browser_session.start() # start the session yourself before passing to Agent
|
|
...
|
|
agent = Agent(..., browser_session=browser_session)
|
|
await agent.run()
|
|
...
|
|
await browser_session.kill() # end the session yourself, shortcut for keep_alive=False + .stop()
|
|
```
|
|
|
|
## Re-Using a Browser
|
|
|
|
A `BrowserSession` starts when the browser is launched/connected, and ends when the browser process exits/disconnects. A session internally manages a single live playwright browser context, and is normally auto-closed by the agent when its task is complete (*if* the agent started the session itself). If you pass an existing `BrowserSession` into an Agent, or if you set `BrowserSession(keep_alive=True)`, the session will not be closed and can be re-used between agents.
|
|
|
|
Browser Use provides a number of ways to re-use profiles, sessions, and other configuration across multiple agents.
|
|
|
|
- ✅ sequential agents can re-use a single `user_data_dir` in new `BrowserSession`s
|
|
- ✅ sequential agents can re-use a single `BrowserSession` without closing it
|
|
- ❌ parallel agents cannot run separate `BrowserSession`s using the same `user_data_dir`
|
|
- ✅ parallel agents can run separate `BrowserSession`s using the same `storage_state`
|
|
- ✅ parallel agents can share a single `BrowserSession`, working in different tabs
|
|
- ⚠️ parallel agents can share a single `BrowserSession`, working in the same tab
|
|
|
|
<Important>
|
|
Multiple `BrowserSession`s (aka chrome processes) cannot share the same `user_data_dir` at the same time, but they can share a `storage_state` file or `BrowserProfile` config.
|
|
</Important>
|
|
|
|
### Sequential Agents, Same Profile, Different Browser
|
|
|
|
If you are only running one agent & browser at a time, they can re-use the same `user_data_dir` sequentially.
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
from langchain_openai import ChatOpenAI
|
|
|
|
reused_profile = BrowserProfile(user_data_dir='~/.config/browseruse/profiles/default')
|
|
|
|
agent1 = Agent(
|
|
task="The first task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_profile=reused_profile, # pass the profile in, it will auto-create a session
|
|
)
|
|
await agent1.run()
|
|
|
|
agent2 = Agent(
|
|
task="The second task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_profile=reused_profile, # agent will auto-create its own new session
|
|
)
|
|
await agent2.run()
|
|
```
|
|
|
|
> Make sure to never mix different browser versions or `executable_path`s with the same `user_data_dir`. Once run with a newer browser version, some migrations are applied to the dir and older browsers wont be able to read it.
|
|
|
|
### Sequential Agents, Same Profile, Same Browser
|
|
|
|
If you are only running one agent at a time, they can re-use the same active `BrowserSession` and avoid having to relaunch chrome.
|
|
Each agent will start off looking at the same tab the last agent ended off on.
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
from langchain_openai import ChatOpenAI
|
|
|
|
reused_session = BrowserSession(
|
|
user_data_dir='~/.config/browseruse/profiles/default',
|
|
keep_alive=True, # dont close browser after 1st agent.run() ends
|
|
)
|
|
await reused_session.start() # when keep_alive=True, session must be started manually
|
|
|
|
agent1 = Agent(
|
|
task="The first task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=reused_session,
|
|
)
|
|
await agent1.run()
|
|
|
|
agent2 = Agent(
|
|
task="The second task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=reused_session, # re-use the same session
|
|
)
|
|
await agent2.run()
|
|
|
|
await reused_session.close()
|
|
```
|
|
|
|
### Parallel Agents, Same Browser, Multiple Tabs
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
from langchain_openai import ChatOpenAI
|
|
|
|
shared_browser = BrowserSession(
|
|
storage_state='/tmp/cookies.json',
|
|
user_data_dir=None,
|
|
keep_alive=True,
|
|
headless=True,
|
|
)
|
|
await shared_browser.start() # when keep_alive=True, you must start the session yourself
|
|
|
|
agent1 = Agent(
|
|
task="The first task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=shared_browser, # pass the session in
|
|
)
|
|
agent2 = Agent(
|
|
task="The second task...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=shared_browser, # re-use the same session
|
|
)
|
|
await asyncio.gather(agent1.run(), agent2.run()) # run in parallel
|
|
|
|
await shared_browser.close()
|
|
```
|
|
|
|
### Parallel Agents, Same Browser, Same Tab
|
|
|
|
<Warning>
|
|
⚠️ This mode is not recommended. Agents are not yet optimized to share the same tab in the same browser, they may interfere with each other or cause errors.
|
|
</Warning>
|
|
|
|
|
|
```python
|
|
from browser_use import Agent, BrowserSession
|
|
from langchain_openai import ChatOpenAI
|
|
from playwright.async_api import async_playwright
|
|
|
|
playwright = await async_playwright().start()
|
|
browser = await playwright.chromium.launch(headless=True)
|
|
context = await browser.new_context()
|
|
shared_page = await context.new_page()
|
|
await shared_page.goto('https://example.com', wait_until='domcontentloaded')
|
|
|
|
shared_session = BrowserSession(page=shared_page, keep_alive=True)
|
|
await shared_session.start()
|
|
|
|
agent1 = Agent(
|
|
task="Fill out the form in section A...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=shared_session
|
|
)
|
|
agent2 = Agent(
|
|
task="Fill out the form in section B...",
|
|
llm=ChatOpenAI(model="gpt-4o-mini"),
|
|
browser_session=shared_session,
|
|
)
|
|
await asyncio.gather(agent1.run(), agent2.run()) # run in parallel
|
|
|
|
await shared_session.kill()
|
|
```
|
|
|
|
### Parallel Agents, Same Profile, Different Browsers
|
|
|
|
<Tip>
|
|
This mode is the recommended default.
|
|
</Tip>
|
|
|
|
To share a single set of configuration or cookies, but still have agents working in their own browser sessions (potentially in parallel), use our provided `BrowserProfile` object.
|
|
|
|
The recommended way to re-use cookies and localStorage state between separate parallel sessions is to use the [`storage_state`](https://docs.browser-use.com/customize/browser-settings#storage-state) option.
|
|
|
|
```bash
|
|
# open a browser to log into sites you want the Agent to have access to
|
|
playwright open https://example.com/ --save-storage=/tmp/auth.json
|
|
playwright open https://example.com/ --load-storage=/tmp/auth.json
|
|
```
|
|
|
|
```python
|
|
from browser_use.browser import BrowserProfile, BrowserSession
|
|
|
|
shared_profile = BrowserProfile(
|
|
headless=True,
|
|
user_data_dir=None, # use dedicated tmp user_data_dir per session
|
|
storage_state='/tmp/auth.json', # load/save cookies to/from json file
|
|
keep_alive=True, # don't close the browser after the agent finishes
|
|
)
|
|
|
|
window1 = BrowserSession(browser_profile=profile_a)
|
|
await window1.start()
|
|
agent1 = Agent(browser_session=window1)
|
|
|
|
window2 = BrowserSession(browser_profile=profile_a)
|
|
await window2.start()
|
|
agent2 = Agent(browser_session=window2)
|
|
|
|
await asyncio.gather(agent1.run(), agent2.run()) # run in parallel
|
|
await window1.save_storage_state() # write storage state (cookies, localStorage, etc.) to auth.json
|
|
await window2.save_storage_state() # you must decide when to save manually
|
|
|
|
# can also reload the cookies from the file into the active session if they change
|
|
await window1.load_storage_state()
|
|
await window1.close()
|
|
await window2.close()
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Chrome Won't Connect
|
|
|
|
If you're having trouble connecting:
|
|
|
|
1. **Close all Chrome instances** before trying to launch with a custom profile
|
|
2. **Check if Chrome is running with debugging port**:
|
|
```bash
|
|
ps aux | grep chrome | grep remote-debugging-port
|
|
```
|
|
3. **Verify the executable path** is correct for your system
|
|
4. **Check profile permissions** - ensure your user has read/write access
|
|
|
|
### Profile Lock Issues
|
|
|
|
If you get a "profile is already in use" error:
|
|
|
|
1. Close all Chrome instances
|
|
2. The profile will automatically be unlocked when BrowserSession starts
|
|
3. Alternatively, manually delete the `SingletonLock` file in the profile directory
|
|
|
|
<Note>
|
|
For more configuration options, see the [Browser Settings](/customize/browser-settings) documentation.
|
|
</Note>
|
|
|
|
### Profile Version Issues
|
|
|
|
The browser version you run must always be equal to or greater than the version used to create the `user_data_dir`.
|
|
If you see errors like `Failed to parse Extensions` when launching, you're likely attempting to run an older browser with an incompatible `user_data_dir` that's already been migrated to a newer Chrome version.
|
|
|
|
Playwright ships a version of chromium that's newer than the default stable Google Chrome release channel, so this can happen if you try to use
|
|
a profile created by the default playwright chromium (e.g. `user_data_dir='~/.config/browseruse/profiles/default'`) with an older
|
|
local browser like `executable_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'`.
|