---
name: browser-use
description: "Automate browser interactions — web testing, form filling, screenshots, scraping, multi-tab workflows. Drives a real browser via Playwright/Selenium for production automation: form filling, multi-step navigation, screenshot capture, scraping with auth, file uploads, multi-tab workflows, and the anti-detection patterns to avoid Cloudflare/bot walls."
license: MIT
---

# Browser Use

Browser Use drives a real, headful or headless browser through Playwright (with a Selenium fallback) so an agent can interact with pages the way a person does: clicking, typing, waiting on network, and reading rendered DOM. It is built for developers who need automation that survives JavaScript-heavy SPAs, authentication walls, and bot-detection layers — not brittle HTTP scraping.

## When to use it

- End-to-end testing of a login flow, checkout, or multi-step wizard where each step depends on rendered state.
- Scraping data that only exists after client-side rendering, infinite scroll, or behind a session cookie.
- Filling and submitting forms (including file uploads and date pickers) across one or several tabs.
- Capturing full-page or element screenshots for visual regression or reporting.
- Reaching sites guarded by Cloudflare, PerimeterX, or similar where a plain `requests` call returns a challenge page.

## How it works

Each action maps to a Playwright primitive. Navigation uses `page.goto(url, wait_until="networkidle")`. Elements are targeted with role/text locators (`page.get_by_role`, `page.get_by_text`) rather than raw CSS to stay resilient to markup changes. Interactions auto-wait via `locator.click()`, `locator.fill()`, and `expect(locator).to_be_visible()`. Uploads use `set_input_files`; multi-tab work is handled through `context.pages` and `context.expect_page()`. Screenshots come from `page.screenshot(full_page=True)`. Persistent auth is saved and replayed with `storage_state` JSON, so you log in once. Anti-detection relies on `playwright-stealth` patches plus realistic `user_agent`, `locale`, and `viewport` on the browser context.

## Example

```python
# saved as scrape_orders.py
ctx = browser.new_context(storage_state="auth.json", locale="en-US")
page = ctx.new_page()
page.goto("https://app.example.com/orders", wait_until="networkidle")
page.get_by_role("button", name="Export").click()
with page.expect_download() as dl:
    page.get_by_text("Download CSV").click()
dl.value.save_as("./orders.csv")
page.screenshot(path="orders.png", full_page=True)
```

## Tips & gotchas

- Prefer `wait_until="networkidle"` over fixed `sleep` calls; arbitrary sleeps are the top cause of flaky runs.
- Generate `auth.json` once with a headful login, then reuse it — re-authenticating on every run is what trips rate limits and detection.
- Stealth patches reduce fingerprinting but do not defeat CAPTCHA. For hard challenges, route through a CAPTCHA-solving service or a residential proxy.
- Run headless in CI but reproduce failures with `headless=False` and `slow_mo=500` to watch what actually happens.

## FAQ

**Playwright or Selenium?** Playwright is the default — faster, auto-waiting, better multi-tab handling. Selenium is available for legacy Grid setups or unusual driver requirements.

**Can it bypass Cloudflare?** It clears most passive JS challenges via stealth and a real browser context. Interactive CAPTCHAs still require a solver or human-in-the-loop.

**How do I keep a session logged in?** Save `context.storage_state(path="auth.json")` after login and pass it to `new_context(storage_state=...)` on later runs.
