selenium-driverless

repository·master·Indexed 21 days ago

https://github.com/ttlns/selenium-driverless

A Python library for controlling Chrome using Selenium-like syntax without chromedriver to avoid bot detection. It supports asyncio, multiple isolated contexts, and advanced CDP-based interactions, including human-like mouse paths, randomized element clicks, and network request interception via NetworkInterceptor.

Tokens
16.3K
Snippets
61
Records
81
Agent score
74%

What's inside selenium-driverless

  1. Simulate realistic mouse paths

    master
    To avoid detection, the library can generate and execute mouse paths that mimic human movement. These paths can be generated as a sequence of mouse movement events. You can use these generated paths to test browser interactions or replay real human movement patterns (e.g., from a mousepad or high-frequency mouse) to achieve high-frequency event rates (up to 180 events/sec using getCoalescedEvents logic) that match screen frequencies or higher.
  2. Simulate human-like element clicks

    master
    The library supports simulating element clicks with varying degrees of randomness to avoid detection. By default, clicks follow a standard pattern, but you can introduce bias to simulate more human-like interaction patterns. This is useful for bypassing bot detection systems that look for perfectly consistent interaction coordinates.
  3. Basic usage with asyncio

    master

    To use selenium-driverless, import webdriver from selenium_driverless. The library is designed for asynchronous execution using asyncio. You should use an async with context manager to manage the lifecycle of the webdriver.Chrome instance.

    Key capabilities demonstrated in the example:

    • Navigating to a URL with driver.get(url, wait_load=True).
    • Waiting for specific CDP (Chrome DevTools Protocol) events using driver.wait_for_cdp(event_name, timeout).
    • Finding elements using driver.find_element(By, selector, timeout).
    • Performing interactions like elem.click(move_to=True).
    • Handling browser alerts via driver.switch_to.alert.
    from selenium_driverless import webdriver
    from selenium_driverless.types.by import By
    import asyncio
    
    
    async def main():
        options = webdriver.ChromeOptions()
        async with webdriver.Chrome(options=options) as driver:
            await driver.get('http://nowsecure.nl#relax', wait_load=True)
            await driver.sleep(0.5)
            await driver.wait_for_cdp("Page.domContentEventFired", timeout=15)
    
            # wait 10s for elem to exist
            elem = await driver.find_element(By.XPATH, '/html/body/div[2]/div/main/p[2]/a', timeout=10)
            await elem.click(move_to=True)
    
            alert = await driver.switch_to.alert
            print(alert.text)
            await alert.accept()
    
            print(await driver.title)
    
    
    asyncio.run(main())
  4. Use selenium-driverless with asyncio

    master

    The recommended way to use selenium-driverless is with asyncio. This allows for efficient handling of multiple tabs and asynchronous operations. Use async with webdriver.Chrome(...) to manage the driver lifecycle.

    Key features in the async API:

    • driver.get(url, wait_load=True): Navigates to a URL.
    • driver.wait_for_cdp(event, timeout): Waits for a specific Chrome DevTools Protocol event.
    • driver.find_element(by, selector, timeout): Finds an element with a specified timeout.
    • elem.click(move_to=True): Performs a click, optionally moving the pointer to the element first.
    from selenium_driverless import webdriver
    from selenium_driverless.types.by import By
    import asyncio
    
    
    async def main():
        options = webdriver.ChromeOptions()
        async with webdriver.Chrome(options=options) as driver:
            await driver.get('http://nowsecure.nl#relax', wait_load=True)
            await driver.sleep(0.5)
            await driver.wait_for_cdp("Page.domContentEventFired", timeout=15)
            
            # wait 10s for elem to exist
            elem = await driver.find_element(By.XPATH, '/html/body/div[2]/div/main/p[2]/a', timeout=10)
            await elem.click(move_to=True)
    
            alert = await driver.switch_to.alert
            print(alert.text)
            await alert.accept()
    
            print(await driver.title)
    
    
    asyncio.run(main())
  5. Manage multiple tabs simultaneously

    master

    To work with multiple tabs in parallel, use asyncio.gather along with driver.new_window("tab", activate=False) to create new tabs without losing focus on the current one. Each tab can be treated as a target object.

    from selenium_driverless.sync import webdriver
    from selenium_driverless.utils.utils import read
    from selenium_driverless import webdriver
    import asyncio
    
    
    async def target_1_handler(target):
        await target.get('https://abrahamjuliot.github.io/creepjs/')
        print(await target.title)
    
    
    async def target_2_handler(target):
        await target.get("about:blank")
        await target.execute_script(await script=read("/files/js/show_mousemove.js"))
        await target.pointer.move_to(500, 500, total_time=2)
    
    
    async def main():
        options = webdriver.ChromeOptions()
        async with webdriver.Chrome(options=options) as driver:
            target_1 = await driver.current_target
            target_2 = await driver.new_window("tab", activate=False)
            await asyncio.gather(
                target_1_handler(target_1),
                target_2_handler(target_2)
            )
            await target_1.focus()
            input("press ENTER to exit")
    
    
    asyncio.run(main())
  6. Install selenium-driverless

    master

    To use selenium-driverless, ensure you have Python >= 3.8 and Google-Chrome installed (Chromium is not tested).

    Install the package via pip:

    pip install selenium-driverless

    If you want to use the latest implementations from the development branch, you can install directly from GitHub:

    pip uninstall -y selenium-driverless
    pip install https://github.com/kaliiiiiiiiii/Selenium-Driverless/archive/refs/heads/dev.zip
    pip install selenium-driverless
  7. Use selenium-driverless synchronously

    master

    A synchronous API is available via selenium_driverless.sync. Note that this is an asyncified wrapper, so bugs may be expected.

    Use with webdriver.Chrome(options=options) to manage the driver context.

    from selenium_driverless.sync import webdriver
    
    options = webdriver.ChromeOptions()
    with webdriver.Chrome(options=options) as driver:
        driver.get('http://nowsecure.nl#relax')
        driver.sleep(0.5)
        driver.wait_for_cdp("Page.domContentEventFired", timeout=15)
    
        title = driver.title
        url = driver.current_url
        source = driver.page_source
        print(title)
  8. Intercept network requests with NetworkInterceptor

    master

    Use the NetworkInterceptor class to monitor and intercept network traffic within selenium-driverless. The interceptor acts as an asynchronous iterator that yields InterceptedRequest objects, allowing you to inspect or modify requests as they occur.

    # Example usage pattern for request interception
    from selenium_driverless.scripts.network_interceptor import NetworkInterceptor
    
    async def intercept_example(driver):
        async with NetworkInterceptor(driver) as interceptor:
            async for intercepted_request in interceptor:
                # Handle the intercepted request
                print(f"Intercepted: {intercepted_request.url}")
  9. Configure Chrome Preferences

    master

    You can set Chrome preferences using options.update_pref() or by updating the options.prefs dictionary directly. This is useful for settings like disabling download prompts.

    from selenium_driverless import webdriver
    options = webdriver.ChromeOptions()
    
    # recommended usage
    options.update_pref("download.prompt_for_download", False)
    # or
    options.prefs.update({"download": {"prompt_for_download": False}})
    # or
    options.add_experimental_option("prefs", {"download": {"prompt_for_download": False}})
  10. Manage browser sessions with the Context class

    master

    The Context class allows you to drive the browser without using chromedriver. It manages browser targets, windows, and session-level configurations like incognito mode and download behaviors. You can use it as an asynchronous context manager to ensure the session is properly started and quit.

    async with Context(base_target=my_target, is_incognito=True) as context:
        await context.get("https://example.com")
        # perform actions
    # session is automatically quit here
  11. Configure ChromeOptions for selenium-driverless

    master

    The Options class (equivalent to webdriver.ChromeOptions) is used to configure the Chrome browser instance.

    Important: Options objects should not be reused across different driver instances.

    Key capabilities include:

    • Setting the binary location for Chromium.
    • Configuring headless mode.
    • Managing user data directories and download directories.
    • Setting proxies and extensions.
    • Modifying browser preferences.
    from selenium_driverless import webdriver
    
    options = webdriver.ChromeOptions()
    # Configure options here
    async with webdriver.Chrome(options=options) as driver:
        await driver.get('https://example.com')