diff --git a/README.md b/README.md index e4c5063..2ed5042 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ * Overwrite **device metrics** using Selenium * Mobile and Desktop **emulation** -* **Undetected** by Google, Cloudflare, creep-js .. +* **Undetected** by Google, Cloudflare, creep-js using [selenium-driverless](# with selenium-driverless) * [Modifying headers](#Modify-headers) supported using [Selenium-Interceptor](https://github.com/kaliiiiiiiiii/Selenium-Interceptor) or seleniumwire -* [Touch Actions](#Touch_actions) +* [Touch Actions](# Touch_actions) * dynamic proxies with authentication * making single [POST](https://github.com/kaliiiiiiiiii/Selenium-Profiles/discussions/11#discussioncomment-4797109), GET or other requests using `driver.profiles.fetch(url)` ([syntax](https://developer.mozilla.org/en-US/docs/Web/API/fetch#syntax)) * headless unofficially supported @@ -118,6 +118,29 @@ profile = \ } ``` +### with selenium-driverless +warning: +- this package is experimental and might include bugs, please report them at [bug-reports](https://github.com/kaliiiiiiiiii/Selenium-Driverless/issues) +- only for python >=3.8 +```python +from selenium_profiles.webdriver import Chrome +from selenium_profiles.profiles import profiles +from selenium_driverless.webdriver import ChromeOptions +from selenium_driverless.types.by import By + +profile = profiles.Windows() # or .Android +options = ChromeOptions() +# options.add_argument("--headless=new") +driver = Chrome(profile, options=options, driverless_options=True) + +# get url +driver.get('https://nowsecure.nl#relax') # test fingerprint + +driver.quit() # Execute on the End! +``` +see [documentation](https://github.com/kaliiiiiiiiii/Selenium-Driverless) for usages + + ### Modify-headers using selenium-wire diff --git a/setup.py b/setup.py index 00c728e..783024e 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,14 @@ import sys -requirements = ['selenium', 'requests', 'selenium-interceptor', "undetected-chromedriver", "selenium-wire", "webdriver-manager", "selenium-injector>=2.3"] +requirements = ['selenium', 'requests', 'selenium-interceptor', + "undetected-chromedriver", "selenium-wire", "webdriver-manager", + "selenium-injector>=2.3"] + +py_version = sys.version_info +if py_version.major >= 3 and py_version.minor >= 8: + # requires python >= 3.8 + requirements.append("selenium-driverless>=1.2.1") if 'google.colab' in sys.modules: # we're on google-colab requirements.extend(['PyVirtualDisplay', "google-colab-shell"]) diff --git a/src/selenium_profiles/__init__.py b/src/selenium_profiles/__init__.py index 4633bc0..23bc6ef 100644 --- a/src/selenium_profiles/__init__.py +++ b/src/selenium_profiles/__init__.py @@ -1 +1 @@ -__version__ = "2.2.7.4" +__version__ = "2.2.8" diff --git a/src/selenium_profiles/scripts/profiles.py b/src/selenium_profiles/scripts/profiles.py index 1f72ab7..269c148 100644 --- a/src/selenium_profiles/scripts/profiles.py +++ b/src/selenium_profiles/scripts/profiles.py @@ -222,6 +222,7 @@ def __init__(self, options, options_profile: dict or None = None, duplicate_poli options_profile = {} self.profile = defaultdict(lambda: None) self.profile.update(options_profile) + self._extensions = [] self.duplicate_policy = duplicate_policy self.duplicates = defaultdict(lambda: set()) @@ -527,6 +528,6 @@ def add_extensions(self, extension_paths: None or list = None, adb: bool or None warnings.warn("Extension-file isn't *.zip or *.crx") self.Options.add_extension(extension_path) elif os.path.isdir(extension_path): - self.add_argument('--load-extension=' + extension_path) + self._extensions.append(extension_path) else: raise LookupError("Extension-path doesn't exist") diff --git a/src/selenium_profiles/webdriver.py b/src/selenium_profiles/webdriver.py index a8be2ea..0ba1010 100644 --- a/src/selenium_profiles/webdriver.py +++ b/src/selenium_profiles/webdriver.py @@ -12,9 +12,10 @@ class Chrome(BaseDriver): # noinspection PyDefaultArgument def __init__(self, profile: dict = None, chrome_binary: str = None, executable_path: str = None, - options=None, duplicate_policy: str = "warn-add", safe_duplicates: list = ["--add-extension"], + options=None, duplicate_policy: str = "warn-add", safe_duplicates: list = list(), base_drivers:tuple=None, - uc_driver: bool or None = None, seleniumwire_options: dict or bool or None = None, injector_options:dict or bool or None = None, + uc_driver: bool or None = None, seleniumwire_options: dict or bool or None = None, + injector_options:dict or bool or None = None, driverless_options = None, **kwargs): import seleniumwire.undetected_chromedriver as wire_uc_webdriver @@ -47,6 +48,14 @@ def __init__(self, profile: dict = None, chrome_binary: str = None, executable_p from selenium.webdriver import ChromeOptions options = ChromeOptions() + if driverless_options: + try: + # noinspection PyUnresolvedReferences + from selenium_driverless.sync.webdriver import Chrome as DriverlessChrome + except: + raise RuntimeError("selenium-driverless requires Python>=3.8") + base_drivers = base_drivers + (DriverlessChrome,) + if len(base_drivers) > 1: warnings.warn("More than one base_driver might not initialize correctly, seems buggy.\n Also, you might try different order") if (len(base_drivers) == 1) and (base_drivers[0] == Chrome.__base__): @@ -105,6 +114,8 @@ def __init__(self, profile: dict = None, chrome_binary: str = None, executable_p if (uc_webdriver.Chrome in base_drivers) or (wire_uc_webdriver.Chrome in base_drivers): if executable_path: kwargs.update({"driver_executable_path": executable_path}) + elif driverless_options: + pass else: # detectability options from selenium_profiles.scripts import undetected @@ -130,10 +141,12 @@ def __init__(self, profile: dict = None, chrome_binary: str = None, executable_p if (injector_options is True) or injector_options == {}: injector_options = {} injector = Injector(**injector_options) + options_manager.add_extensions(injector.paths) - options_manager.add_argument(f'--load-extension={",".join(injector.paths)}') # add options to kwargs + # noinspection PyProtectedMember,PyUnresolvedReferences + options_manager.add_argument(f'--load-extension={",".join(options_manager._extensions)}') kwargs.update({"options": options_manager.Options}) # Actual start of chrome