Playwright bot-detection probe — score CDP for webdriver and headless leaks. CLI: cdp-probe.
Project description
playwright-cdp-probe
Playwright bot-detection probe — score CDP sessions for webdriver, headless Chrome, and WebGL exposure.
pip install playwright-cdp-probe
cdp-probe check-local
CLI: cdp-probe · Python 3.10+ · optional [mlx] for Launcher helpers
Coupon hub: Verified MLX deals (
SAAS50browser /MIN50cloud phone) — Multilogin promo codes. Core CLI works without a vendor account. Affiliate disclosure.
Audit Playwright and CDP browser sessions for automation exposure signals — navigator.webdriver, chrome.runtime, plugin counts, permissions API, headless UA hints, and window/WebGL fingerprints.
Returns a 0–100 exposure score (higher = more detectable automation artifacts). Use in CI, before production deploys, or to compare vanilla Chromium vs isolated antidetect profiles.
Problem
Bot-detection stacks probe dozens of browser signals beyond IP and cookies. Before shipping automation to production, teams need a quick way to answer:
- Does this browser context leak
navigator.webdriver? - Are headless or SwiftShader fingerprints visible?
- How does a CDP-attached session compare to a local Playwright launch?
cdp-probe launches Playwright (or connects over CDP), collects signals in-page, and scores automation exposure with a reproducible report.
Install
pip install playwright-cdp-probe
playwright install chromium # first-time browser binaries
Optional Multilogin X launcher integration (compare isolated profile scores — not required for core probe):
pip install playwright-cdp-probe[mlx]
Development:
pip install playwright-cdp-probe[dev]
Quick start
# Baseline: how detectable is default Playwright Chromium?
cdp-probe check-local --browser chromium
# Probe a live page (login gates, dashboards, SaaS apps)
cdp-probe run --url https://example.com
# Site-class presets (weighted for common gate pages — see presets/)
cdp-probe run --preset cloudflare --url https://example.com
cdp-probe run --preset stripe-dashboard --url https://dashboard.stripe.com
cdp-probe run --preset social-login --url https://example.com/login
# CI / GitHub Actions annotations
cdp-probe run --url https://example.com --format github-actions
# Re-print the last report
cdp-probe report --format table
cdp-probe report --format json
from playwright_cdp_probe import ProbeRunner
from playwright_cdp_probe.probe import ProbeOptions
report = ProbeRunner(ProbeOptions(url="https://example.com")).run()
print(report.exposure.score, report.exposure.grade)
for finding in report.exposure.findings:
print(finding.signal, finding.detail)
CLI
| Command | Description |
|---|---|
cdp-probe run --url URL |
Launch browser, navigate, score exposure |
cdp-probe run --preset NAME --url URL |
Score with site-class weights (presets/) |
cdp-probe check-local --browser chromium|firefox |
Probe about:blank locally |
cdp-probe report --format json|table|github-actions |
Format last saved report |
cdp-probe mlx --profile-id UUID |
MLX Launcher → CDP probe → stop ([mlx] extra) |
cdp-probe --show-deal |
Print partner coupon info (opt-in only) |
Exit codes
| Code | Meaning |
|---|---|
0 |
pass — exposure score ≤ 30 |
1 |
warn — exposure score 31–60 |
2 |
fail — exposure score > 60 |
3 |
Runtime / validation error |
Signal weights and bands: docs/SCORING.md.
Presets
| Preset | Best for | Signals emphasized |
|---|---|---|
cloudflare |
Turnstile / JS challenge pages | HeadlessChrome UA, webdriver, SwiftShader WebGL |
stripe-dashboard |
Payment / SaaS dashboards | Thin plugins, missing chrome.runtime |
social-login |
OAuth popups | webdriver, headless window dimensions |
Reports save to ~/.cache/cdp-probe/last-report.json (override with --output).
When exposure scores stay high
Vanilla Playwright Chromium often lands in the warn or fail band — that is expected, not a misconfiguration.
| Step | Action |
|---|---|
| 1 | Read findings in cdp-probe report --format table — which signals fired? |
| 2 | Lint static fingerprint config with fingerprint-coherence (fp-coherence audit) |
| 3 | Re-probe over remote CDP or an antidetect Launcher port instead of launch() |
| 4 | Compare scores: check-local vs profile-attached session — quantify the delta |
| 5 | Validate proxy + cookies: proxy-lane-checker → cookie-jar-bridge |
Full fleet QA pipeline:
proxy-lane check proxies.txt -o lanes.json
fp-coherence audit profile.yaml --strict
cdp-connect mlx-start --profile-id UUID --print-cdp-url # peer: cdp-connect-kit
cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com --format github-actions
cookie-bridge validate session-cookies.txt --strict
Coupon hub: Multilogin promo codes — guides for SAAS50 / MIN50, pricing comparisons, and workflow playbooks.
Isolated antidetect browsers provision OS, screen, WebGL, and storage at the profile level — often a better fix than patching individual JS APIs. If you evaluate Multilogin X for production profile pools, see Production (affiliate disclosure applies; core probe needs no vendor account).
API
| Symbol | Description |
|---|---|
ProbeRunner |
Launch Playwright or connect_over_cdp, collect signals |
ProbeOptions |
url, browser, headless, cdp_endpoint |
compute_exposure_score(signals) |
Score 0–100 with weighted findings |
ProbeReport |
Signals + exposure + timestamp |
format_report(report, "json"|"table") |
CLI-compatible formatting |
Signals collected
navigator.webdriverwindow.chrome.runtime(Chromium)navigator.plugins/mimeTypescountsnavigator.permissionsAPI presenceNotification.permission- HeadlessChrome user-agent hint
- Window outer/inner dimension mismatch
- WebGL vendor/renderer (SwiftShader detection)
Limitations
- Not a bypass tool — measures exposure; does not patch, spoof, or hide fingerprints.
- Vanilla Chrome/Playwright leaks at scale — default launches routinely expose
webdriverand headless WebGL. High scores are normal. - Page-level only — TLS/JA3, IP reputation, behavioral biometrics, and server-side ML are out of scope.
- Single-page snapshot — one navigation moment, not long-session drift.
- Firefox signal set differs —
chrome.runtimechecks apply to Chromium only. - MLX requires desktop agent —
mlxneeds Multilogin running locally. See docs/MLX_INTEGRATION.md.
Production
For isolated antidetect profiles, connect Playwright over a Launcher CDP endpoint instead of launching vanilla Chromium:
export MLX_TOKEN="your-bearer-token"
export MLX_FOLDER_ID="your-folder-uuid"
cdp-probe mlx --profile-id PROFILE_UUID --url https://example.com
from playwright_cdp_probe.integrations.mlx import mlx_launch_and_probe
report = mlx_launch_and_probe(
"profile-id",
folder_id="folder-id",
token="...",
url="https://example.com",
)
print(report.exposure.score)
Compare check-local (vanilla) vs mlx (profile) to quantify exposure reduction — not elimination.
Partner note (affiliate): If Multilogin X fits your workflow (profile pools, folder scale, Launcher CDP), eligible new browser purchases may accept code SAAS50 at checkout on the official site — verify current terms before paying. Full disclosure: docs/AFFILIATE.md. Deals hub: anti-detect.github.io. Coupon details only via cdp-probe --show-deal (never printed by default).
FAQ: docs/FAQ.md — Playwright detection, headless Chrome, CDP exposure, antidetect comparison.
Related tools (on PyPI)
| Package | CLI | Role |
|---|---|---|
| playwright-cdp-probe | cdp-probe |
CDP / WebDriver exposure score |
| cookie-jar-bridge | cookie-bridge |
Netscape ↔ Playwright cookies |
| proxy-lane-checker | proxy-lane |
Proxy TCP / HTTP / geo / DNSBL |
| fingerprint-coherence | fp-coherence |
UA / screen / timezone lint |
Toolkit pipeline: proxy-lane check → fp-coherence audit → automate → cdp-probe run → cookie-bridge validate
License
MIT
Production antidetect: Multilogin X · Code SAAS50 (-50% browser) · MIN50 (-50% cloud phone)
More scripts: @Multilogin_Scripts_Bot · Multilogin promo codes
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file playwright_cdp_probe-0.2.4.tar.gz.
File metadata
- Download URL: playwright_cdp_probe-0.2.4.tar.gz
- Upload date:
- Size: 52.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb0d84ae2139abebb402b83f35ad88ac148269f6aa7b8c7ffd2dd34f75c27e96
|
|
| MD5 |
ff6c5f38208153cda29ed790d52451d1
|
|
| BLAKE2b-256 |
44955ffded299793eb173496a3a0aa9e9109a33aea91bb10097af5f955fc308c
|
File details
Details for the file playwright_cdp_probe-0.2.4-py3-none-any.whl.
File metadata
- Download URL: playwright_cdp_probe-0.2.4-py3-none-any.whl
- Upload date:
- Size: 28.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ed60b34a89317ba929fb965f342b48bdfb186e06edb607bff7c9cf81daf09d9
|
|
| MD5 |
1f3253e5e8b9c1474d4324d625342548
|
|
| BLAKE2b-256 |
7cbb45d95b3dadcce47d66253001a08f3eae4252afe44bf5415ff60ae138acac
|