Skip to main content

Make your playwright instance stealthy

Project description

playwright_stealth

Fork of AtuboDad's port of puppeteer-extra-plugin-stealth, with some improvements. Don't expect this to bypass anything but the simplest of bot detection methods. Consider this a proof-of-concept starting point.

I've merged some of the outstanding PRs, added some features, and cleaned up the API surface. See the changelog. The latest major version includes breaking changes.

Install

Install from PyPi:

$ pip install playwright-stealth

Example Usage

Recommended Usage

import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import Stealth


async def main():
    # This is the recommended usage. All pages created will have stealth applied:
    async with Stealth().use_async(async_playwright()) as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()

        webdriver_status = await page.evaluate("navigator.webdriver")
        print("from new_page: ", webdriver_status)

        different_context = await browser.new_context()
        page_from_different_context = await different_context.new_page()

        different_context_status = await page_from_different_context.evaluate("navigator.webdriver")
        print("from new_context: ", different_context_status)


asyncio.run(main())

Specifying config options and applying evasions manually to an entire context

import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import Stealth, ALL_EVASIONS_DISABLED_KWARGS


async def advanced_example():
    # Custom configuration with specific languages
    custom_languages = ("fr-FR", "fr")
    stealth = Stealth(
        navigator_languages_override=custom_languages,
        init_scripts_only=True
    )

    async with async_playwright() as p:
        browser = await p.chromium.launch()
        context = await browser.new_context()
        await stealth.apply_stealth_async(context)

        # Test stealth on multiple pages
        page_1 = await context.new_page()
        page_2 = await context.new_page()

        # Verify language settings
        for i, page in enumerate([page_1, page_2], 1):
            is_mocked = await page.evaluate("navigator.languages") == custom_languages
            print(f"Stealth applied to page {i}: {is_mocked}")

    # Example of selective evasion usage
    no_evasions = Stealth(**ALL_EVASIONS_DISABLED_KWARGS)
    single_evasion = Stealth(**{**ALL_EVASIONS_DISABLED_KWARGS, "navigator_webdriver": True})

    print("Total evasions (none):", len(no_evasions.script_payload))
    print("Total evasions (single):", len(single_evasion.script_payload))


asyncio.run(advanced_example())

Todo

  • make this work with playwright.launch_persistent_context
    • the difficult because sometimes we sniff the UA if an override isn't provided, and this is difficult to do when launch_persistent_context is launched
  • sec-platform (we have navigator_platform)
  • docs

A set of Test results

playwright with stealth

playwright without stealth

playwright without stealth

playwright with stealth

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

playwright_stealth-2.0.2.tar.gz (24.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

playwright_stealth-2.0.2-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file playwright_stealth-2.0.2.tar.gz.

File metadata

  • Download URL: playwright_stealth-2.0.2.tar.gz
  • Upload date:
  • Size: 24.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.1 CPython/3.11.13 Linux/6.18.7-arch1-1

File hashes

Hashes for playwright_stealth-2.0.2.tar.gz
Algorithm Hash digest
SHA256 ac57e51873190da5e653e03720e948c8f0a3d06b098f1d56763103d23ee48143
MD5 58f9463e0f3b8151a4b1d40531497cae
BLAKE2b-256 61ee871901103c7b2a12070011fd4d978191f8f962837bf8bb51847274f528fa

See more details on using hashes here.

File details

Details for the file playwright_stealth-2.0.2-py3-none-any.whl.

File metadata

  • Download URL: playwright_stealth-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 33.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.1 CPython/3.11.13 Linux/6.18.7-arch1-1

File hashes

Hashes for playwright_stealth-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 37a5733f481b9c0ad602cf71491aa5a7c96c2a2fe4fa1e7ab764d2cd35520f2f
MD5 ae4bfc71536e08905c91a778c183d40d
BLAKE2b-256 f130f95f087f4b071611a7f63a2a0c9af4df3ac046dae2a693bfdacd70512867

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page