kaliiiiiiiiii / Selenium-Driverless

undetected Selenium without usage of chromedriver
https://kaliiiiiiiiii.github.io/Selenium-Driverless/
Other
430 stars 52 forks source link

WebdriverWait is not compatible #77

Closed henzycuong1 closed 9 months ago

henzycuong1 commented 9 months ago

Example Code:

import sys
sys.path.append(".")
import multiprocessing
import time
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.common.exceptions import *
from colorama import Fore, init
from selenium_driverless.sync import webdriver
from selenium.common.exceptions import *

TIMEOUT = 40

def executing(
    dir_chrome
):
    options = webdriver.ChromeOptions()
    options.add_argument(f'--user-data-dir={dir_chrome}\\Data\\profile')
    with webdriver.Chrome(options=options) as driver:
        wait = WebDriverWait(driver=driver, timeout=TIMEOUT)
        driver.get('https://abrahamjuliot.github.io/creepjs/')
        wait.until(ec.visibility_of_element_located((By.XPATH,'//span[@class="unblurred"]')))
        input("WAIT")
        driver.quit(clean_dirs=False)

def do(dir_chrome):
    init(convert=True)
    sys.stdin = open(0)

    executing(f"{dir_chrome}\\Data\\profile")

def main():
    manager = multiprocessing.Manager()
    processes = []
    processes.append(multiprocessing.Process(target=do, args=('D:\ChromePortable\Profile 1',))) 
    # processes.append(multiprocessing.Process(target=do, args=('D:\ChromePortable\Profile 2'))) 
    # processes.append(multiprocessing.Process(target=do, args=('D:\ChromePortable\Profile 3'))) 
    [p.start() for p in processes]
    [p.join() for p in processes]

if __name__ == "__main__":
    multiprocessing.freeze_support()
    init(convert=True)
    count = time.time()
    main()
    print(Fore.YELLOW + f"Done || Time elapsed: {time.time() - count}" + Fore.RESET)

Error:

Traceback (most recent call last):
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\support\wait.py", line 86, in until
    value = method(self._driver)
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 151, in _predicate
    return _element_if_visible(driver.find_element(*locator))
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium_driverless\sync\webdriver.py", line 38, in syncified
    return self._loop.run_until_complete(res(*args, **kwargs))
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
    return future.result()
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium_driverless\webdriver.py", line 662, in find_element
    return await target.find_element(by=by, value=value, parent=parent, timeout=timeout)
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium_driverless\types\target.py", line 523, in find_element
    return await parent.find_element(by=by, value=value, timeout=timeout)
  File "C:\Users\Four\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium_driverless\types\webelement.py", line 249, in find_element
    raise NoSuchElementException()
selenium_driverless.types.webelement.NoSuchElementException

Reason:

Solution: Command class NoSuchElementException(Exception) and import NoSuchElementException from selenium core. It look like this image

you don't have to create new webdriverwait because in webdriverwait selenium core just need driver and running in a while

kaliiiiiiiiii commented 9 months ago

@henzycuong1 Yep, I'm aware of that. However, my plan is to remove the Selenium dependency.

Therefore, all those:

from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

Won't work.

My reason to do that, is because I really don't like the syntax of selenium's WebdriverWait.

In my oppinion, something like: elem.wait_for(cond.visible) * and a timout (wait until exist) at driver.find_elements(timeout:float or None) ** would be way neater. I could add something like WebdriverWait to be supported additionally. The native one from selenium won't ever be supported due to structural incompatibilities.

* not implemented yet * * already implemented

Also, I plan to add a propper documentation btw:)

If you really ned Full support for selenium, maybe https://github.com/g1879/DrissionPage is probably. more what you need (unfortanely no english documentation available).

henzycuong1 commented 9 months ago

@kaliiiiiiiiii thank you, maybe I'll have to change so much in my project