Integrations / Automation libraries / Playwright for Python
Playwright for Python, with profiles that remember.
launch_persistent_context keeps cookies in a folder, but every folder still looks like the same browser on the same machine. A Browz profile keeps its cookies and has its own fingerprint and proxy. The Python SDK starts it; Playwright attaches with connect_over_cdp.
pip install playwright browz-mcpSetup
Set it up.
Install Browz and open it
Download Browz and leave it open.
Install the packages
The Browz SDK is in the
browz-mcppackage on PyPI and uses only the standard library. Noplaywright installis needed: Browz provides the browser.Terminalpip install playwright browz-mcpStart, attach, clean up
browz_session()creates a profile and starts it; on exit it stops it and, unless you passkeep=True, deletes it. The Playwright block closes first, so it detaches before Browz stops the browser.run.pyfrom playwright.sync_api import sync_playwright from browz.agents import browz_session with browz_session(name="research-nyc", keep=True) as session, sync_playwright() as p: browser = p.chromium.connect_over_cdp(session.ws_endpoint or session.cdp_endpoint) context = browser.contexts[0] # the profile’s own cookies and storage page = context.pages[0] if context.pages else context.new_page() page.goto("https://example.com") print(page.title()) browser.close() # detaches; browz_session stops the profile
API from Playwright for Python connect_over_cdp.
Example
Come back to a signed-in profile (async).
Sign in once by hand in the profile’s window, then let scripts reuse it. reuse=True attaches to the profile if it is already open, and the script stops it only if it started it.
import asyncio
from playwright.async_api import async_playwright
from browz import Browz
from browz.agents import local_credentials
async def main():
host, token = local_credentials()
browz = Browz(token=token, host=host)
profile = next(p for p in browz.profiles.list() if p["name"] == "research-nyc")
session = browz.browser.start(profile["id"], reuse=True)
try:
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(session.cdp_endpoint)
page = browser.contexts[0].pages[0]
await page.goto("https://example.com")
print(await page.title())
await browser.close()
finally:
if not session.already_running:
browz.browser.stop(profile["id"])
asyncio.run(main())Good to know
Notes and tips.
- Never call
p.chromium.launch()for a Browz profile: that starts a stock browser with automation flags and none of the profile’s fingerprint, proxy or cookies. Attach to the one Browz started. - The SDK calls are synchronous; in async code they block for the length of one local request, which is short. Wrap them in
asyncio.to_threadif that matters to you. - Attach to the browser Browz started; never let the library launch its own. A library-launched browser is a stock one with none of the profile’s fingerprint, proxy or cookies.
- A person completes sign-ins, 2FA codes and CAPTCHAs in the profile’s window; your script can wait for the page that follows. Browz never solves or bypasses CAPTCHAs.
- Automate only where each site’s terms allow it. Our acceptable use policy applies to scripts the same as to people.
- The local API, CDP and the SDKs are on every plan, Free included (5 profiles), and are not metered.
FAQ
Playwright for Python and Browz.
Is the Python SDK on PyPI?
Yes, in the browz-mcp package: pip install browz-mcp, then import browz. It has no dependencies outside the standard library.
Where does the token come from?
local_credentials() reads BROWZ_TOKEN if it is set, otherwise the api-token file in the Browz data folder (~/.browz by default). The token is never printed.
Can I use pytest-playwright?
Yes, with your own browser fixture that starts a profile and connects over CDP instead of the plugin’s launched browser.
Get started
Download Browz. Every task, its own browser.
curl -fsSL https://gobrowz.com/agents/install.sh | sh