#
Puppeteer
Integrate Puppeteer with Kameleo to automate browsing using realistic, spoofed browser fingerprints (Chroma kernel only).
You can start a profile in two ways:
- Explicit start: Create the profile via the Local API and call
startProfile. Use this when you need custom command-line switches, proxy settings, flags, or advanced options. - Auto-start: Skip
startProfile. When Puppeteer connects with the WebSocket endpoint, Kameleo automatically starts the profile using defaults.
After either approach, you control the browser with normal Puppeteer commands, then clean up (stop / export / delete) the profile.
#
Prerequisites
- Completion of the Quickstart guide
- A Puppeteer-compatible environment (Python, JavaScript, or C# with Puppeteer library installed)
#
Limitations & best practices
- Puppeteer works only with Chroma (Chromium-based) kernels.
- Do not add third-party stealth / fingerprint patches (puppeteer-extra-plugin-stealth, Canvas defenders, etc.). They can reduce masking quality.
- Use one browser context per profile. Create multiple Kameleo profiles instead of multiple contexts.
#
Option 1: Explicitly start the profile (customizable)
Use this when you must set advanced startup parameters. Example below show a start with some custom settings.
#
1. Create a profile
from kameleo.local_api_client import KameleoLocalApiClient
from kameleo.local_api_client.models import CreateProfileRequest
client = KameleoLocalApiClient(endpoint='http://localhost:5050')
fingerprints = client.fingerprint.search_fingerprints(
device_type='desktop',
browser_product='chrome'
)
create_req = CreateProfileRequest(
fingerprint_id=fingerprints[0].id,
name='puppeteer explicit start example'
)
profile = client.profile.create_profile(create_req)
import { KameleoLocalApiClient } from "@kameleo/local-api-client";
const client = new KameleoLocalApiClient({ basePath: "http://localhost:5050" });
const fingerprints = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome");
const createProfileRequest = { fingerprintId: fingerprints[0].id, name: "puppeteer explicit start example" };
const profile = await client.profile.createProfile(createProfileRequest);
using Kameleo.LocalApiClient;
using Kameleo.LocalApiClient.Model;
var client = new KameleoLocalApiClient(new Uri("http://localhost:5050"));
var fingerprints = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome");
var createProfileRequest = new CreateProfileRequest(fingerprints[0].Id) { Name = "puppeteer explicit start example" };
var profile = await client.Profile.CreateProfileAsync(createProfileRequest);
#
2. Start the profile (customization point)
Below are three common customization patterns. Pick one (or combine arguments + preferences) before connecting Puppeteer. The browser must be stopped and restarted to apply a different set.
- Add command-line arguments (e.g. mute audio)
- Pass extra options / capabilities (e.g. disable background throttling)
- Set native browser preferences (e.g. disable images)
from kameleo.local_api_client.models import BrowserSettings, Preference
client.profile.start_profile(profile.id, BrowserSettings(
arguments=["mute-audio"],
additional_options=[
Preference(key='pageLoadStrategy', value='eager'),
],
preferences=[
Preference(key='profile.managed_default_content_settings.images', value=2),
]
))
await client.profile.startProfile(profile.id, {
browserSettings: {
arguments: ["mute-audio"],
additionalOptions: [{ key: "pageLoadStrategy", value: "eager" }],
preferences: [{ key: "profile.managed_default_content_settings.images", value: 2 }],
},
});
using Kameleo.LocalApiClient.Model;
await client.Profile.StartProfileAsync(profile.Id, new BrowserSettings(
arguments: new List<string> { "mute-audio" },
additionalOptions: new List<Preference> {
new Preference("pageLoadStrategy", "eager"),
},
preferences: new List<Preference> {
new Preference("profile.managed_default_content_settings.images", 2),
}
));
#
3. Connect Puppeteer (Chroma only)
Use the WebSocket URL ws://localhost:{port}/puppeteer/{profileId} to connect.
import pyppeteer
browser_ws_endpoint = f'ws://localhost:5050/puppeteer/{profile.id}'
browser = await pyppeteer.launcher.connect(browserWSEndpoint=browser_ws_endpoint, defaultViewport=False)
import puppeteer from "puppeteer";
const browserWSEndpoint = `ws://localhost:5050/puppeteer/${profile.id}`;
const browser = await puppeteer.connect({
browserWSEndpoint,
defaultViewport: null,
});
using PuppeteerSharp;
var browserWsEndpoint = $"ws://localhost:5050/puppeteer/{profile.Id}";
var browser = await Puppeteer.ConnectAsync(new ConnectOptions
{
BrowserWSEndpoint = browserWsEndpoint,
DefaultViewport = null
});
#
4. Run Puppeteer commands
page = await browser.newPage()
await page.goto('https://google.com')
const page = await browser.newPage();
await page.goto("https://google.com");
var page = await browser.NewPageAsync();
await page.GoToAsync("https://google.com");
#
Option 2: Auto-start the profile (simpler)
Skip the explicit start call. Kameleo starts the profile automatically on the first Puppeteer connection. Use this for quick scripts where default startup behavior is enough.
#
1. Create the profile (same as before, no start call later)
from kameleo.local_api_client import KameleoLocalApiClient
from kameleo.local_api_client.models import CreateProfileRequest
import pyppeteer, asyncio
async def main():
client = KameleoLocalApiClient(endpoint='http://localhost:5050')
fps = client.fingerprint.search_fingerprints(device_type='desktop', browser_product='chrome')
profile = client.profile.create_profile(CreateProfileRequest(
fingerprint_id=fps[0].id,
name='puppeteer auto-start example'
))
browser_ws_endpoint = f'ws://localhost:5050/puppeteer/{profile.id}'
browser = await pyppeteer.launcher.connect(browserWSEndpoint=browser_ws_endpoint, defaultViewport=False)
page = await browser.newPage()
await page.goto('https://wikipedia.org')
client.profile.stop_profile(profile.id)
asyncio.run(main())
import { KameleoLocalApiClient } from "@kameleo/local-api-client";
import puppeteer from "puppeteer";
const client = new KameleoLocalApiClient({ basePath: "http://localhost:5050" });
const fps = await client.fingerprint.searchFingerprints("desktop", undefined, "chrome");
const profile = await client.profile.createProfile({ fingerprintId: fps[0].id, name: "puppeteer auto-start example" });
const browserWSEndpoint = `ws://localhost:5050/puppeteer/${profile.id}`;
const browser = await puppeteer.connect({ browserWSEndpoint, defaultViewport: null });
const page = await browser.newPage();
await page.goto("https://wikipedia.org");
await client.profile.stopProfile(profile.id);
using Kameleo.LocalApiClient;
using Kameleo.LocalApiClient.Model;
using PuppeteerSharp;
var client = new KameleoLocalApiClient(new Uri("http://localhost:5050"));
var fps = await client.Fingerprint.SearchFingerprintsAsync(deviceType: "desktop", browserProduct: "chrome");
var profile = await client.Profile.CreateProfileAsync(new CreateProfileRequest(fps[0].Id) { Name = "puppeteer auto-start example" });
var browserWsEndpoint = $"ws://localhost:5050/puppeteer/{profile.Id}";
var browser = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = browserWsEndpoint, DefaultViewport = null });
var page = await browser.NewPageAsync();
await page.GoToAsync("https://wikipedia.org");
await client.Profile.StopProfileAsync(profile.Id);
#
Cleanup (stop, export, delete)
Always stop the profile to persist its state. Optionally export it for backup or delete it to reclaim space.
#
Stop, export, or delete
import os
from kameleo.local_api_client.models import ExportProfileRequest
client.profile.stop_profile(profile.id)
export_path = f'{os.path.dirname(os.path.realpath(__file__))}/test.kameleo'
client.profile.export_profile(profile.id, body=ExportProfileRequest(path=export_path))
client.profile.delete_profile(profile.id)
await client.profile.stopProfile(profile.id);
await client.profile.exportProfile(profile.id, { body: { path: `${import.meta.dirname}/test.kameleo` } });
await client.profile.deleteProfile(profile.id);
using Kameleo.LocalApiClient.Model;
await client.Profile.StopProfileAsync(profile.Id);
await client.Profile.ExportProfileAsync(profile.Id, new ExportProfileRequest(Path.Combine(Environment.CurrentDirectory, "test.kameleo")));
await client.Profile.DeleteProfileAsync(profile.Id);