From 8123a1b0adcac6ee9c0ee10074f0cbc6cfbb8602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Co=C5=9Fkun=20Deniz?= Date: Fri, 1 Nov 2024 17:21:02 +0300 Subject: [PATCH] Add troubleshooting section and handle failsafe exception --- README.md | 21 ++++++++ search_controller.py | 118 ++++++++++++++++++++++++++----------------- 2 files changed, 94 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 1ee1a11..7fbcce1 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,27 @@ Apply the following steps for once to enable Telegram notifications.
+## Troubleshooting + +#### 1. ValueError: max() arg is an empty sequence + +* If you see this error, run the following commands. + + 1. Delete `.MULTI_BROWSERS_IN_USE` file if exists. + * `rm .MULTI_BROWSERS_IN_USE` for Linux or `del .MULTI_BROWSERS_IN_USE` for Windows. + + 2. Run `python ad_clicker.py -q test` and end it by pressing CTRL+C after seeing the browser opened. + + 3. Continue with one of the commands from [How to run](#how-to-run) section. + +#### 2. Chrome version mismatch error + +* If you get an error like **"This version of ChromeDriver only supports Chrome version ... Current browser version is ..."**, it means you are using an older Chrome version and should update to the latest one. + +* You may need to apply [solution from the previous section](#1-valueerror-max-arg-is-an-empty-sequence) for some cases. + +
+ ## Support [https://coskundeniz.github.io/ad_clicker](https://coskundeniz.github.io/ad_clicker) diff --git a/search_controller.py b/search_controller.py index de2805d..a8f04b4 100644 --- a/search_controller.py +++ b/search_controller.py @@ -13,6 +13,7 @@ from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import ( + JavascriptException, TimeoutException, NoSuchElementException, ElementNotInteractableException, @@ -379,7 +380,11 @@ def _handle_browser_click( self._driver.execute_script("arguments[0].scrollIntoView(true);", link_element) self._open_link_in_new_tab(link_element) - logger.debug("Opened link in a new tab. Switching to tab...") + if len(self._driver.window_handles) != 2: + logger.debug(f"Failed to open '{link_url}' in a new tab!") + return + else: + logger.debug("Opened link in a new tab. Switching to tab...") for window_handle in self._driver.window_handles: if window_handle != original_window_handle: @@ -425,14 +430,24 @@ def _open_link_in_new_tab( platform = sys.platform control_command_key = Keys.COMMAND if platform.endswith("darwin") else Keys.CONTROL - actions = ActionChains(self._driver) - actions.move_to_element(link_element) - actions.key_down(control_command_key) - actions.click() - actions.key_up(control_command_key) - actions.perform() - - sleep(get_random_sleep(0.5, 1)) + try: + actions = ActionChains(self._driver) + actions.move_to_element(link_element) + actions.key_down(control_command_key) + actions.click() + actions.key_up(control_command_key) + actions.perform() + + sleep(get_random_sleep(0.5, 1)) + + except JavascriptException as exp: + error_message = str(exp).split("\n")[0] + + if "has no size and location" in error_message: + logger.error( + f"Failed to click element[{link_element.get_attribute('outerHTML')}]! " + "Skipping..." + ) def _get_wait_time(self, is_ad_element: bool) -> int: """Get wait time based on whether the link is an ad or non-ad @@ -976,57 +991,70 @@ def _make_random_mouse_movements(self) -> None: """Make random mouse movements""" if self._random_mouse_enabled: - import pyautogui + try: + import pyautogui + + logger.debug("Making random mouse movements...") + + screen_width, screen_height = pyautogui.size() + pyautogui.moveTo(screen_width / 2 - 300, screen_height / 2 - 200) - logger.debug("Making random mouse movements...") + logger.debug(pyautogui.position()) - screen_width, screen_height = pyautogui.size() - pyautogui.moveTo(screen_width / 2 - 300, screen_height / 2 - 200) + ease_methods = [ + pyautogui.easeInQuad, + pyautogui.easeOutQuad, + pyautogui.easeInOutQuad, + ] - logger.debug(pyautogui.position()) + logger.debug("Going LEFT and DOWN...") - ease_methods = [pyautogui.easeInQuad, pyautogui.easeOutQuad, pyautogui.easeInOutQuad] + pyautogui.move( + -random.choice(range(200, 300)), + random.choice(range(250, 450)), + 1, + random.choice(ease_methods), + ) - logger.debug("Going LEFT and DOWN...") + logger.debug(pyautogui.position()) - pyautogui.move( - -random.choice(range(200, 300)), - random.choice(range(250, 450)), - 1, - random.choice(ease_methods), - ) + for _ in range(1, random.choice(range(3, 7))): + direction = random.choice(list(Direction)) + ease_method = random.choice(ease_methods) - logger.debug(pyautogui.position()) + logger.debug(f"Going {direction.value}...") - for _ in range(1, random.choice(range(3, 7))): - direction = random.choice(list(Direction)) - ease_method = random.choice(ease_methods) + if direction == Direction.LEFT: + pyautogui.move(-(random.choice(range(100, 200))), 0, 0.5, ease_method) - logger.debug(f"Going {direction.value}...") + elif direction == Direction.RIGHT: + pyautogui.move(random.choice(range(200, 400)), 0, 0.3, ease_method) - if direction == Direction.LEFT: - pyautogui.move(-(random.choice(range(100, 200))), 0, 0.5, ease_method) + elif direction == Direction.UP: + pyautogui.move(0, -(random.choice(range(100, 200))), 1, ease_method) + pyautogui.scroll(random.choice(range(1, 7))) - elif direction == Direction.RIGHT: - pyautogui.move(random.choice(range(200, 400)), 0, 0.3, ease_method) + elif direction == Direction.DOWN: + pyautogui.move(0, random.choice(range(150, 300)), 0.7, ease_method) + pyautogui.scroll(-random.choice(range(1, 7))) - elif direction == Direction.UP: - pyautogui.move(0, -(random.choice(range(100, 200))), 1, ease_method) - pyautogui.scroll(random.choice(range(1, 7))) + else: + pyautogui.move( + random.choice(range(100, 200)), + random.choice(range(150, 250)), + 1, + ease_method, + ) - elif direction == Direction.DOWN: - pyautogui.move(0, random.choice(range(150, 300)), 0.7, ease_method) - pyautogui.scroll(-random.choice(range(1, 7))) + logger.debug(pyautogui.position()) - else: - pyautogui.move( - random.choice(range(100, 200)), - random.choice(range(150, 250)), - 1, - ease_method, - ) + except pyautogui.FailSafeException: + logger.debug("The mouse cursor was moved to one of the screen corners!") - logger.debug(pyautogui.position()) + pyautogui.FAILSAFE = False + + logger.debug("Moving cursor to center...") + pyautogui.moveTo(screen_width / 2, screen_height / 2) def _check_captcha(self) -> None: """Check if captcha exists and solve it if 2captcha is used, otherwise exit"""