Undetected selenium without chromedriver usage
Project description
Selenium-Driverless
- use selenium without chromedriver
- currently passes cloudfare, bet365, turnstile and others
- multiple tabs simultanously
- multiple Incognito-contexts with individual proxy & cookies
- async (
asyncio
) and sync (experimantal) support
Feel free to test my code!
See dev-branch for the latest implementations.
Installation with pip install https://github.com/kaliiiiiiiiii/Selenium-Driverless/archive/refs/heads/dev.zip
Getting Started
Dependencies
- Python >= 3.7
- Chrome-Browser installed
Installing
- Install Chrome-Browser
pip install selenium-driverless
Usage
with asyncio
from selenium_driverless import webdriver
import asyncio
async def main():
options = webdriver.ChromeOptions()
async with webdriver.Chrome(options=options) as driver:
await driver.get('http://nowsecure.nl#relax')
await driver.implicitly_wait(0.5)
await driver.wait_for_cdp("Page.domContentEventFired", timeout=15)
title = await driver.title
url = await driver.current_url
source = await driver.page_source
print(title)
asyncio.run(main())
synchronous
asyncified, might be buggy
from selenium_driverless.sync import webdriver
options = webdriver.ChromeOptions()
with webdriver.Chrome(options=options) as driver:
driver.get('http://nowsecure.nl#relax')
driver.implicitly_wait(0.5)
driver.wait_for_cdp("Page.domContentEventFired", timeout=15)
title = driver.title
url = driver.current_url
source = driver.page_source
print(title)
custom debugger address
from selenium_driverless import webdriver
options = webdriver.ChromeOptions()
options.debugger_address = "127.0.0.1:2005"
# specify if you don't want to run remote
# options.add_argument("--remote-debugging-port=2005")
async with webdriver.Chrome(options=options) as driver:
await driver.get('http://nowsecure.nl#relax', wait_load=True)
use events
Note: synchronous might not work properly
from selenium_driverless import webdriver
import asyncio
global driver
async def on_request(params):
await driver.execute_cdp_cmd("Fetch.continueRequest", {"requestId": params['requestId']},
disconnect_connect=False)
print(params["request"]["url"])
async def main():
global driver
options = webdriver.ChromeOptions()
async with webdriver.Chrome(options=options) as driver:
await driver.get('http://nowsecure.nl#relax')
# enable Fetch, we don't want to disconnect after "Fetch.enable"
await driver.execute_cdp_cmd("Fetch.enable", disconnect_connect=False)
await driver.add_cdp_listener("Fetch.requestPaused", on_request)
await driver.wait_for_cdp(event="Page.loadEventFired", timeout=5)
await driver.remove_cdp_listener("Fetch.requestPaused", on_request)
await driver.execute_cdp_cmd("Fetch.disable")
print(await driver.title)
asyncio.run(main())
Multiple tabs simultously
Note: asyncio
is recommendet, threading
has been reported not too work
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(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.switch_to.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())
Unique execution contexts
from selenium_driverless.sync import webdriver
from selenium_driverless import webdriver
import asyncio
async def main():
options = webdriver.ChromeOptions()
async with webdriver.Chrome(options=options) as driver:
await driver.get('chrome://version')
script = """
const proxy = new Proxy(document.documentElement, {
get(target, prop, receiver) {
if(prop === "outerHTML"){
console.log('detected access on "'+prop+'"', receiver)
return "mocked value:)"
}
else{return Reflect.get(...arguments)}
},
});
Object.defineProperty(document, "documentElement", {
value: proxy
})
"""
await driver.execute_script(script)
src = await driver.execute_script("return document.documentElement.outerHTML", unique_context=True)
mocked = await driver.execute_script("return document.documentElement.outerHTML", unique_context=False)
print(src, mocked)
asyncio.run(main())
Pointer Interaction
see @master/dev/show_mousemove.py for visualization
pointer = await driver.current_pointer
move_kwargs = {"total_time": 0.7, "accel": 2, "smooth_soft": 20}
await pointer.move_to(100, 500)
await pointer.click(500, 50, move_kwargs=move_kwargs, move_to=True)
Iframes
iframes = await driver.find_elements(By.TAG_NAME, "iframe")
await asyncio.sleep(0.5)
target = await driver.get_target_for_iframe(iframes[0])
multiple contexts
- different cookies for each context
- A context can have multiple windows and tabs within
- different proxy for each context
- opens as a window as incognito
Help
Please feel free to open an issue or fork! note: please check the todo's below at first!
Todo
- implementations
-
WebDriverWait
-
EC
(expected-conditions) -
driver.switch_to.frame
workaround -
ActionChains
-
execute_script
andexecute_async_script
- make serialization use
deep
- add
Page.createIsolatedWorld
support withDOM
access- make
element.rect
use this - make
elem.box_model use this
- make
- make serialization use
- support
options.add_extension()
-
- sync
- move sync to threaded for allowing event_handlers
- support multithreading with sync version
Deprecated
Authors
License
Unless specified differently in a single file, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Disclaimer
I am not responsible what you use the code for!!! Also no warranty!
Acknowledgments
Inspiration, code snippets, etc.
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
File details
Details for the file selenium_driverless-1.5.tar.gz
.
File metadata
- Download URL: selenium_driverless-1.5.tar.gz
- Upload date:
- Size: 61.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
a8b97fe05c441073cface9dc81ad666ee2ed7306d487f5816e91a083fb3824a2
|
|
MD5 |
b7abdcfb6ffaf291e5a311c358b956bd
|
|
BLAKE2b-256 |
38a183517eb19d2238d8cc416ed3c3406ec2b7347058324fa49b37304ade0537
|