Quickstart

  1. Launch a browser
    1. Python (sync)
    2. Python (async)
    3. Node
  2. Watch it run while you build
    1. Python
    2. Node
  3. Using a proxy
    1. Python
    2. Node
  4. Match the timezone to your proxy
    1. Python
    2. Node
  5. Scrape a page
    1. Python
    2. Node
  6. Go faster by blocking heavy resources
    1. Python
    2. Node
  7. Contexts and pages
  8. First-run download

Launch a browser

Python (sync)

from chromiumfish.sync_api import Chromiumfish

with Chromiumfish(persona_seed="alpha-7", headless=True) as browser:
    page = browser.new_page()
    page.goto("https://example.com")
    page.screenshot(path="fingerprint.png")

Python (async)

import asyncio
from chromiumfish.async_api import AsyncChromiumfish

async def main():
    async with AsyncChromiumfish(persona_seed="alpha-7") as browser:
        page = await browser.new_page()
        await page.goto("https://example.com")
        print(await page.title())

asyncio.run(main())

Node

import { ChromiumFish } from "chromiumfish";

const browser = await ChromiumFish({ personaSeed: "alpha-7", headless: true });
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "fingerprint.png" });
await browser.close();

The object you get back is a standard Playwright Browser. Use contexts, pages, routing, tracing, and selectors exactly as you would with vanilla Playwright.

Watch it run while you build

Launches are headless by default. While you’re writing a selector or stepping through a login, open a visible window with headless=False and drop into the Playwright Inspector with page.pause().

Python

with Chromiumfish(persona_seed="alpha-7", headless=False) as browser:
    page = browser.new_page()
    page.goto("https://example.com")
    page.pause()   # opens the Inspector; step through and pick selectors

Node

const browser = await ChromiumFish({ personaSeed: "alpha-7", headless: false });
const page = await browser.newPage();
await page.goto("https://example.com");
await page.pause();

Headful mode needs a display. On a headless server, run under xvfb-run, or just keep headless=True and use page.screenshot(...) to see what the page looked like.

Using a proxy

Python

with Chromiumfish(
    persona_seed="alpha-7",
    proxy={
        "server": "http://proxy.example.com:8000",
        "username": "user",
        "password": "pass",
    },
) as browser:
    ...

Node

const browser = await ChromiumFish({
  personaSeed: "alpha-7",
  proxy: { server: "http://proxy.example.com:8000", username: "user", password: "pass" },
});

Pair a residential proxy with a matching persona for best results. A clean IP plus a coherent fingerprint clears most bot walls. Keep the proxy’s geo consistent with the persona’s locale.

Match the timezone to your proxy

A browser whose clock sits in a different timezone than its IP address is an easy tell. Set timezone="auto" and the SDK resolves the egress IP to an IANA timezone (using the downloadable ip2tz DB) and sets the browser’s timezone to match.

Python

with Chromiumfish(
    persona_seed="alpha-7",
    proxy={"server": "http://proxy.example.com:8000"},
    timezone="auto",
) as browser:
    page = browser.new_page()
    page.goto("https://example.com")

Node

const browser = await ChromiumFish({
  personaSeed: "alpha-7",
  proxy: { server: "http://proxy.example.com:8000" },
  timezone: "auto",
});

If you already know the location, pass an IANA name directly, for example timezone="Europe/Berlin" (Python) or timezone: "Europe/Berlin" (Node). Leaving it out disables timezone handling entirely.

Scrape a page

A small but realistic flow: open a page, wait for the network to settle, pull a bit of text and an attribute, then save a screenshot.

Python

from chromiumfish.sync_api import Chromiumfish

with Chromiumfish(persona_seed="alpha-7") as browser:
    page = browser.new_page()
    page.goto("https://example.com", wait_until="domcontentloaded")

    title = page.inner_text("h1")
    link = page.get_attribute("a", "href")
    print(title, link)

    page.screenshot(path="screenshot.png", full_page=True)

Node

import { ChromiumFish } from "chromiumfish";

const browser = await ChromiumFish({ personaSeed: "alpha-7" });
const page = await browser.newPage();
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });

const title = await page.innerText("h1");
const link = await page.getAttribute("a", "href");
console.log(title, link);

await page.screenshot({ path: "screenshot.png", fullPage: true });
await browser.close();

Go faster by blocking heavy resources

Most scrapes don’t need images, video, or web fonts. Abort those requests with Playwright routing and pages load noticeably faster on slow proxies.

Python

with Chromiumfish(persona_seed="alpha-7") as browser:
    page = browser.new_page()
    page.route(
        "**/*",
        lambda route: route.abort()
        if route.request.resource_type in ("image", "media", "font")
        else route.continue_(),
    )
    page.goto("https://example.com", wait_until="domcontentloaded")

Node

const browser = await ChromiumFish({ personaSeed: "alpha-7" });
const page = await browser.newPage();
await page.route("**/*", (route) => {
  const type = route.request().resourceType();
  return ["image", "media", "font"].includes(type)
    ? route.abort()
    : route.continue();
});
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });

Blocking fonts can change text metrics on some sites. If a page renders oddly or a fingerprint check cares about fonts, drop "font" from the block list.

Contexts and pages

with Chromiumfish(persona_seed="alpha-7") as browser:
    context = browser.new_context(locale="en-US")
    page = context.new_page()
    page.goto("https://example.com")

First-run download

On the first launch (or chromiumfish fetch), the build is downloaded and cached. Subsequent runs reuse the cache, so startup is fast.


Back to top

An independent fork of Chromium. Not affiliated with or endorsed by Google.

This site uses Just the Docs, a documentation theme for Jekyll.