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"""