{"id":17677725,"url":"https://github.com/kaliiiiiiiiii/selenium-driverless","last_synced_at":"2025-05-14T10:11:52.252Z","repository":{"id":182858038,"uuid":"669155940","full_name":"kaliiiiiiiiii/Selenium-Driverless","owner":"kaliiiiiiiiii","description":"a stealthy browser automation framework","archived":false,"fork":false,"pushed_at":"2024-11-23T21:36:56.000Z","size":20379,"stargazers_count":755,"open_issues_count":16,"forks_count":75,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-05T08:44:59.925Z","etag":null,"topics":["automation","detection-evasion","driverless-chrome","python","python3","reverse-engineering","scraping-python","testing","vulnerability-research","web-scraping","webdriver"],"latest_commit_sha":null,"homepage":"https://kaliiiiiiiiii.github.io/Selenium-Driverless/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaliiiiiiiiii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["kaliiiiiiiiii"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"kaliiii","thanks_dev":null,"custom":null}},"created_at":"2023-07-21T13:30:57.000Z","updated_at":"2025-04-04T05:52:36.000Z","dependencies_parsed_at":"2024-01-13T07:31:46.853Z","dependency_job_id":"ce3f28a4-1031-44aa-82ad-da7b50471e4c","html_url":"https://github.com/kaliiiiiiiiii/Selenium-Driverless","commit_stats":null,"previous_names":["kaliiiiiiiiii/selenium-driverless"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliiiiiiiiii%2FSelenium-Driverless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliiiiiiiiii%2FSelenium-Driverless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliiiiiiiiii%2FSelenium-Driverless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaliiiiiiiiii%2FSelenium-Driverless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaliiiiiiiiii","download_url":"https://codeload.github.com/kaliiiiiiiiii/Selenium-Driverless/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248960242,"owners_count":21189979,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","detection-evasion","driverless-chrome","python","python3","reverse-engineering","scraping-python","testing","vulnerability-research","web-scraping","webdriver"],"created_at":"2024-10-24T07:41:41.995Z","updated_at":"2025-04-14T20:43:58.833Z","avatar_url":"https://github.com/kaliiiiiiiiii.png","language":"Python","funding_links":["https://github.com/sponsors/kaliiiiiiiiii","https://buymeacoffee.com/kaliiii"],"categories":[],"sub_categories":[],"readme":"# Driverless (Non-commercial use only!)\n\nNote: This project is moving away from the selenium syntax\n\n[![Downloads](https://static.pepy.tech/badge/selenium-driverless)](https://pepy.tech/project/selenium-driverless) [![](https://img.shields.io/pypi/v/selenium-driverless.svg?color=3399EE)](https://pypi.org/project/selenium-driverless/)\n[Documentation](https://kaliiiiiiiiii.github.io/Selenium-Driverless/#)\n\n\n- Use Selenium __without chromedriver__\n- Currently passes __Cloudflare__, __Bet365__, [Turnstile](https://github.com/kaliiiiiiiiii/Selenium-Driverless/tree/master/dev#bypass-turnstile), and others\n- Multiple tabs simultaneously\n- Multiple Incognito-contexts with isolated cookies \u0026 local storage\n- Proxy-auth support ([example code](https://github.com/kaliiiiiiiiii/Selenium-Driverless/blob/dev/examples/proxy_with_auth.py))\n- Network-interception ([documentation](https://kaliiiiiiiiii.github.io/Selenium-Driverless/api/RequestInterception/))\n- Single requests ([documentation](https://kaliiiiiiiiii.github.io/Selenium-Driverless/api/Target/#selenium_driverless.types.target.Target.fetch))\n\n## Getting detected with interactions?\n[CDP-Patches](https://vinyzu.gitbook.io/cdp-patches-documentation) (headfull only) should fix this \\\n(will integrate it at some time)\n\n### Questions? \nFeel free to join the [Driverless-Community](https://discord.com/invite/MzZZjr2ZM3) on **Discord**:)\n\nAlso, see [dev-branch](https://github.com/kaliiiiiiiiii/Selenium-Driverless/tree/dev) for the latest implementations.\n\u003cdetails\u003e\n\u003csummary\u003edev-installation (click to expand)\u003c/summary\u003e\n\n```shell\npip uninstall -y selenium-driverless\npip install https://github.com/kaliiiiiiiiii/Selenium-Driverless/archive/refs/heads/dev.zip\n```\n\u003c/details\u003e\n\n## Sponsors\n\nThis project is currently not being sponsored.\n\n### Dependencies\n\n* [Python \u003e= 3.8](https://www.python.org/downloads/)\n* [Google-Chrome](https://www.google.de/chrome/) installed (Chromium not tested)\n\n### Installing\n\n* Install [Google-Chrome](https://www.google.de/chrome/)\n* ```pip install selenium-driverless```\n\n\n### Usage\n\n### with asyncio\n```python\nfrom selenium_driverless import webdriver\nfrom selenium_driverless.types.by import By\nimport asyncio\n\n\nasync def main():\n    options = webdriver.ChromeOptions()\n    async with webdriver.Chrome(options=options) as driver:\n        await driver.get('http://nowsecure.nl#relax', wait_load=True)\n        await driver.sleep(0.5)\n        await driver.wait_for_cdp(\"Page.domContentEventFired\", timeout=15)\n        \n        # wait 10s for elem to exist\n        elem = await driver.find_element(By.XPATH, '/html/body/div[2]/div/main/p[2]/a', timeout=10)\n        await elem.click(move_to=True)\n\n        alert = await driver.switch_to.alert\n        print(alert.text)\n        await alert.accept()\n\n        print(await driver.title)\n\n\nasyncio.run(main())\n\n```\n\n### synchronous\nasyncified, bugs are to expect\n\n\u003cdetails\u003e\n\n\u003csummary\u003eexample code\u003c/summary\u003e\n\n```python\nfrom selenium_driverless.sync import webdriver\n\noptions = webdriver.ChromeOptions()\nwith webdriver.Chrome(options=options) as driver:\n    driver.get('http://nowsecure.nl#relax')\n    driver.sleep(0.5)\n    driver.wait_for_cdp(\"Page.domContentEventFired\", timeout=15)\n\n    title = driver.title\n    url = driver.current_url\n    source = driver.page_source\n    print(title)\n```\n\n\u003c/details\u003e\n\n### custom debugger address\n```python\nfrom selenium_driverless import webdriver\n\noptions = webdriver.ChromeOptions()\noptions.debugger_address = \"127.0.0.1:2005\"\n\n# specify if you don't want to run remote\n# options.add_argument(\"--remote-debugging-port=2005\")\n\nasync with webdriver.Chrome(options=options) as driver:\n  await driver.get('http://nowsecure.nl#relax', wait_load=True)\n```\n\n## Multiple tabs simultaneously\nNote: asyncio is recommended, threading only works on independent webdriver.Chrome instances.\n\n\u003cdetails\u003e\n\u003csummary\u003eExample Code (Click to expand)\u003c/summary\u003e\n\n```python\nfrom selenium_driverless.sync import webdriver\nfrom selenium_driverless.utils.utils import read\nfrom selenium_driverless import webdriver\nimport asyncio\n\n\nasync def target_1_handler(target):\n    await target.get('https://abrahamjuliot.github.io/creepjs/')\n    print(await target.title)\n\n\nasync def target_2_handler(target):\n    await target.get(\"about:blank\")\n    await target.execute_script(await script=read(\"/files/js/show_mousemove.js\"))\n    await target.pointer.move_to(500, 500, total_time=2)\n\n\nasync def main():\n    options = webdriver.ChromeOptions()\n    async with webdriver.Chrome(options=options) as driver:\n        target_1 = await driver.current_target\n        target_2 = await driver.new_window(\"tab\", activate=False)\n        await asyncio.gather(\n            target_1_handler(target_1),\n            target_2_handler(target_2)\n        )\n        await target_1.focus()\n        input(\"press ENTER to exit\")\n\n\nasyncio.run(main())\n```\n\n\u003c/details\u003e\n\n### Isolated execution contexts\n- execute `javascript` without getting detected ( in a **isolated world**)\n\u003cdetails\u003e\n\u003csummary\u003eExample Code (Click to expand)\u003c/summary\u003e\n\n```python\nfrom selenium_driverless.sync import webdriver\nfrom selenium_driverless import webdriver\nimport asyncio\n\n\nasync def main():\n    options = webdriver.ChromeOptions()\n    async with webdriver.Chrome(options=options) as driver:\n        await driver.get('chrome://version')\n        script = \"\"\"\n        const proxy = new Proxy(document.documentElement, {\n          get(target, prop, receiver) {\n            if(prop === \"outerHTML\"){\n                console.log('detected access on \"'+prop+'\"', receiver)\n                return \"mocked value:)\"\n            }\n            else{return Reflect.get(...arguments)}\n          },\n        });\n        Object.defineProperty(document, \"documentElement\", {\n          value: proxy\n        })\n        \"\"\"\n        await driver.execute_script(script)\n        src = await driver.execute_script(\"return document.documentElement.outerHTML\", unique_context=True)\n        mocked = await driver.execute_script(\"return document.documentElement.outerHTML\", unique_context=False)\n        print(src, mocked)\n\n\nasyncio.run(main())\n```\n\n\u003c/details\u003e\n\n### Pointer Interaction\nsee [@master/tests/show_mousemove.py](https://github.com/kaliiiiiiiiii/Selenium-Driverless/blob/master/tests/show_mousemove.py) for visualization\n\n```python\npointer = driver.current_pointer\nmove_kwargs = {\"total_time\": 0.7, \"accel\": 2, \"smooth_soft\": 20}\n\nawait pointer.move_to(100, 500)\nawait pointer.click(500, 50, move_kwargs=move_kwargs, move_to=True)\n```\n### Iframes / Frames\ndue `swtich_to.frame()` being deprecated for driverless, use this instead\n\n```python\niframes = await driver.find_elements(By.TAG_NAME, \"iframe\")\nawait asyncio.sleep(0.5)\niframe_document = await iframes[0].content_document\n# iframe_document.find_elements(...)\n```\n\n### use preferences\n```python\nfrom selenium_driverless import webdriver\noptions = webdriver.ChromeOptions()\n\n # recommended usage\noptions.update_pref(\"download.prompt_for_download\", False)\n# or\noptions.prefs.update({\"download\": {\"prompt_for_download\": False}})\n\n# supported\noptions.add_experimental_option(\"prefs\", {\"download.prompt_for_download\": False})\n```\n\n### Multiple Contexts\n- different cookies for each context\n- A context can have multiple windows and tabs within\n- different proxy for each context\n- opens as a window as incognito\n\u003cdetails\u003e\n\u003csummary\u003eExample Code (Click to expand)\u003c/summary\u003e\n\n```python\nfrom selenium_driverless import webdriver\nimport asyncio\n\n\nasync def main():\n    options = webdriver.ChromeOptions()\n    async with webdriver.Chrome(options=options) as driver:\n        context_1 = driver.current_context\n        \n        await driver.set_auth(\"username\", \"password\", \"localhost:5000\")\n        # proxy not supported on windows due to https://bugs.chromium.org/p/chromium/issues/detail?id=1310057\n        context_2 = await driver.new_context(proxy_bypass_list=[\"localhost\"], proxy_server=\"http://localhost:5000\")\n        \n        await context_1.current_target.get(\"https://examle.com\")\n        await context_2.get(\"https://examle.com\")\n        input(\"press ENTER to exit:)\")\n\n\nasyncio.run(main())\n```\n\u003c/details\u003e\n\n#### Custom exception handling\nYou can implement custom exception handling as following\n\n```python\nimport selenium_driverless\nimport sys\nhandler = (lambda e: print(f'Exception in event-handler:\\n{e.__class__.__module__}.{e.__class__.__name__}: {e}',\n                           file=sys.stderr))\nsys.modules[\"selenium_driverless\"].EXC_HANDLER = handler\nsys.modules[\"cdp_socket\"].EXC_HANDLER = handler\n```\n\n## Help\n\nYou found a bug? Feel free to open an issue:)\nYou've got other questions or proposials? feel free to join the [Driverless-Community](https://discord.com/invite/MzZZjr2ZM3) on **Discord** or open a discusion\\\n\n## Copyright and Author\n[Aurin Aegerter](mailto:aurinliun@gmx.ch) (aka **Steve**)\n\n## License\n\n[![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa]\n\nThis work is licensed under a\n[Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License][cc-by-nc-sa] with an **addition for `Section 1(k)`** in the [LEGAL CODE](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.en):\n\n\u003e Commercial means primarily intended for or directed \n\u003e towards commercial advantage or monetary compensation. \\\n\u003e A business, project or public agreement with a commercial intent of any kind\n\u003e which profits more than, or equal to 7'000 US-Dollar per month,\n\u003e or any monetary equivalent to that, is not subject to this definition\n\u003e of NonCommercial.\n\n[cc-by-nc-sa]: http://creativecommons.org/licenses/by-nc-sa/4.0/\n[cc-by-nc-sa-image]: https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png\n[cc-by-nc-sa-shield]: https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg\n\n--- \nIf you wish to use this project commercially, you can contact the author for a custom License.\nThis usually includes a fee of around 5-6% based on your current profit.\n\n## Disclaimer\n\nThis project is meant for **educational purposes only**. Use it responsibly. \\\n**The Author** does **not provide any warranty** and is **not liable** in any way for what or how it gets used.\n\n## Acknowledgments\n\nInspiration, code snippets, etc.\n* [selenium_driverless/utils/find_chrome_executable](https://github.com/ultrafunkamsterdam/undetected-chromedriver/blob/1c704a71cf4f29181a59ecf19ddff32f1b4fbfc0/undetected_chromedriver/__init__.py#L844)\n* [cdp-socket](https://github.com/kaliiiiiiiiii/CDP-Socket)\n* [jsobject](https://pypi.org/project/jsobject/)\n* [pycdp/browser.py](https://github.com/HMaker/python-cdp/blob/master/pycdp/browser.py)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaliiiiiiiiii%2Fselenium-driverless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaliiiiiiiiii%2Fselenium-driverless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaliiiiiiiiii%2Fselenium-driverless/lists"}