Skip to main content

undetected-playwright

Usage

  1. Download PyPi package

    pip install -U undetected-playwright
    
  2. Donload dependencies

    playwright install --with-deps
    
  3. Quick started

    import webbrowser
    from datetime import datetime
    from pathlib import Path
    
    from playwright.sync_api import sync_playwright, Page
    
    from undetected_playwright import Tarnished
    
    
    def cache_screenshot(page: Page):
        _now = datetime.now().strftime("%Y-%m-%d")
        _suffix = f"-view-new-{datetime.now().strftime('%H%M%S')}"
        path = f"result/{_now}/sannysoft{_suffix}.png"
        page.screenshot(path=path, full_page=True)
    
        webbrowser.open(f"file://{Path(path).resolve()}")
    
    
    def main():
        # Chrome 112+
        args = ["--headless=new", "--dump-dom"]
    
        with sync_playwright() as p:
            browser = p.chromium.launch(args=args)
            context = browser.new_context(locale="en-US")
    
            # Injecting Context
            Tarnished.apply_stealth(context)
            page = context.new_page()
    
            page.goto("https://bot.sannysoft.com/", wait_until="networkidle")
            cache_screenshot(page)
    
            browser.close()
    
    
    if __name__ == "__main__":
        main()
    

Demo: SyncPlaywright Sannysoft

import logging
import sys
from datetime import datetime
from enum import Enum

from playwright.sync_api import sync_playwright, Page, Route

from undetected_playwright import Tarnished

logging.basicConfig(
    level=logging.DEBUG, stream=sys.stdout, format="%(asctime)s - %(levelname)s - %(message)s"
)


class ViewMode(str, Enum):
    new = "new"
    headless = "headless"
    headful = "headful"


def _hijacker(route: Route):
    logging.debug(f"{route.request.method} {route.request.url}")
    route.continue_()


def worker(page: Page, view_mode: ViewMode | None = None):
    logging.info(f"Worker started - {view_mode=}")

    page.route("**/*", _hijacker)
    page.goto("https://bot.sannysoft.com/", wait_until="networkidle")

    # Save screenshot
    _now = datetime.now().strftime("%Y-%m-%d")
    if view_mode:
        _suffix = f"-view-{view_mode}"
    else:
        _suffix = f"-view-{datetime.now().strftime('%H%M%S')}"
    page.screenshot(path=f"result/{_now}/sannysoft{_suffix}.png", full_page=True)

    logging.info(f"Worker finished - {view_mode=}")


def bytedance(view_mode: ViewMode):
    with sync_playwright() as p:
        match view_mode:
            case "new":
                args = ["--headless=new", "--dump-dom"]
                browser = p.chromium.launch(args=args)
            case "headless":
                browser = p.chromium.launch(headless=True)
            case _:
                browser = p.chromium.launch(headless=False)

        context = browser.new_context(locale="en-US")
        Tarnished.apply_stealth(context)

        page = context.new_page()
        worker(page, view_mode)

        browser.close()


def main():
    bytedance(ViewMode.new)
    bytedance(ViewMode.headful)
    bytedance(ViewMode.headless)


if __name__ == "__main__":
    main()

Demo: AsyncPlaywright CloudFlare

import asyncio
import logging
import sys
from datetime import datetime
from enum import Enum

from playwright.async_api import async_playwright, Page, Route

from undetected_playwright import Malenia

logging.basicConfig(
    level=logging.DEBUG, stream=sys.stdout, format="%(asctime)s - %(levelname)s - %(message)s"
)


class ViewMode(str, Enum):
    new = "new"
    headless = "headless"
    headful = "headful"


async def _hijacker(route: Route):
    logging.debug(f"{route.request.method} {route.request.url}")
    await route.continue_()


async def worker(page: Page, view_mode: ViewMode | None = None):
    logging.info(f"Worker started - {view_mode=}")

    await page.route("**/*", _hijacker)
    await page.goto("https://www.nowsecure.nl", wait_until="networkidle")

    # Just for demo
    await page.wait_for_timeout(8000)

    # Save screenshot
    _now = datetime.now().strftime("%Y-%m-%d")
    if view_mode:
        _suffix = f"-view-{view_mode}"
    else:
        _suffix = f"-view-{datetime.now().strftime('%H%M%S')}"
    await page.screenshot(path=f"result/{_now}/cloudflare{_suffix}.png", full_page=True)

    logging.info(f"Worker finished - {view_mode=}")


async def bytedance(view_mode: ViewMode):
    async with async_playwright() as p:
        match view_mode:
            case "new":
                args = ["--headless=new", "--dump-dom"]
                browser = await p.chromium.launch(args=args)
            case "headless":
                browser = await p.chromium.launch(headless=True)
            case _:
                browser = await p.chromium.launch(headless=False)

        context = await browser.new_context(locale="en-US")
        await Malenia.apply_stealth(context)

        page = await context.new_page()
        await worker(page, view_mode)

        await browser.close()


async def main():
    await bytedance(ViewMode.new)
    await bytedance(ViewMode.headful)
    await bytedance(ViewMode.headless)


if __name__ == "__main__":
    asyncio.run(main())

Reference

Metadata

Release files for undetected-playwright 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for undetected-playwright 0.3.0
File Size Uploaded Provenance
undetected_playwright-0.3.0.tar.gz 35.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for undetected-playwright 0.3.0
File Interpreter ABI Platform
undetected_playwright-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.7 kB

Release files / undetected_playwright-0.3.0.tar.gz

Download URL undetected_playwright-0.3.0.tar.gz
Size 35.1 kB
Tags Source
SHA-256 checksum
How to use checksums
c476baf095eaea6ee320dd8739e83811da6006227fa9b2492a4e3a8c0cb2b315
BLAKE2b-256 checksum
How to use checksums
526a867b2fb3386e82f902e1d3da0be52266f854209f9f6a4b08b89b9d5d6f3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.10.11 Windows/10

Release files / undetected_playwright-0.3.0-py3-none-any.whl

Download URL undetected_playwright-0.3.0-py3-none-any.whl
Size 55.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dbcc76a6bfdd4ebc849a26c8f084355295ec415af316b1e4fd0a2a011397df92
BLAKE2b-256 checksum
How to use checksums
622687c3790c875d3331972ab0b809d4da0900793c26a700f007fed45d2ecf90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.2 CPython/3.10.11 Windows/10

Security for undetected-playwright 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page