Skip to content

Commit

Permalink
Add wait_factor option
Browse files Browse the repository at this point in the history
  • Loading branch information
coskundeniz committed Jan 19, 2025
1 parent 7351275 commit ff8a13b
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 42 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ The followings are the default values in the config file.
"browser_count": 2,
"multiprocess_style": 1,
"loop_wait_time": 60,
"wait_factor": 1.0,
"running_interval_start": "00:00",
"running_interval_end": "00:00",
"2captcha_apikey": "",
Expand Down Expand Up @@ -201,6 +202,10 @@ The followings are the default values in the config file.

* **loop_wait_time**: Wait time between runs in seconds. Default is 60. Used with `run_in_loop.py`.

* **wait_factor**: Wait factor to modify all sleeps except loop wait. The default value is 1.0.
* For example, if you want to decrease waits by half, you can set this to 0.5, or if you want to increase them by 30%, you can use this as 1.3.
* Note that especially with decreasing, it can make the tool faster but can not guarantee proper functioning.

* **running_interval_start**: Running interval start in "HH:MM" format. Used with `run_in_loop.py`.
* If the current time is outside of the interval, it waits the start time to run again.
* **running_interval_end**: Running interval end in "HH:MM" format. Used with `run_in_loop.py`.
Expand Down
2 changes: 1 addition & 1 deletion ad_clicker.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def main():
from time import sleep

driver.get("https://nowsecure.nl/")
sleep(7)
sleep(7 * config.behavior.wait_factor)

driver.quit()

Expand Down
Binary file modified assets/ad_clicker_gui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"browser_count": 2,
"multiprocess_style": 1,
"loop_wait_time": 60,
"wait_factor": 1.0,
"running_interval_start": "00:00",
"running_interval_end": "00:00",
"2captcha_apikey": "",
Expand Down
2 changes: 2 additions & 0 deletions config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class BehaviorParams:
browser_count: Optional[int] = 2
multiprocess_style: Optional[int] = 1
loop_wait_time: Optional[int] = 60
wait_factor: Optional[float] = 1.0
running_interval_start: Optional[str] = ""
running_interval_end: Optional[str] = ""
twocaptcha_apikey: Optional[str] = ""
Expand Down Expand Up @@ -111,6 +112,7 @@ def read_parameters(self) -> None:
browser_count=multiprocessing.cpu_count() if browser_count == 0 else browser_count,
multiprocess_style=config["behavior"]["multiprocess_style"],
loop_wait_time=config["behavior"]["loop_wait_time"],
wait_factor=config["behavior"]["wait_factor"],
running_interval_start=config["behavior"]["running_interval_start"],
running_interval_end=config["behavior"]["running_interval_end"],
twocaptcha_apikey=config["behavior"]["2captcha_apikey"],
Expand Down
4 changes: 4 additions & 0 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ def __init__(self, master) -> None:
self._loop_wait_time_input = self._add_input_field(
row=7, column=0, label="Loop wait time", default_value=config.behavior.loop_wait_time
)
self._wait_factor_input = self._add_input_field(
row=7, column=3, label="Wait factor", default_value=config.behavior.wait_factor
)

excludes_label = customtkinter.CTkLabel(self, text="Excludes")
excludes_label.grid(row=8, column=0, padx=10, sticky="w")
Expand Down Expand Up @@ -366,6 +369,7 @@ def get_behavior_config(self) -> dict[str, str]:
"browser_count": int(self._browser_count_input.get("1.0", "end-1c")),
"multiprocess_style": int(self._multiprocess_style_input.get("1.0", "end-1c")),
"loop_wait_time": int(self._loop_wait_time_input.get("1.0", "end-1c")),
"wait_factor": float(self._wait_factor_input.get("1.0", "end-1c")),
"running_interval_start": self._running_interval_start_input.get("1.0", "end-1c"),
"running_interval_end": self._running_interval_end_input.get("1.0", "end-1c"),
"2captcha_apikey": self._2captcha_apikey_input.get("1.0", "end-1c"),
Expand Down
4 changes: 2 additions & 2 deletions run_ad_clicker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from typing import Optional

from adb import adb_controller
from logger import logger
from config_reader import config
from logger import logger
from proxy import get_proxies
from utils import get_queries

Expand All @@ -31,7 +31,7 @@ def start_tool(
:param device_id: Android device ID to assign
"""

sleep(start_timeout)
sleep(start_timeout * config.behavior.wait_factor)

command = ["python", "ad_clicker.py"]
command.extend(["-q", query, "-p", proxy, "--id", str(browser_id)])
Expand Down
46 changes: 23 additions & 23 deletions search_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def search_for_ads(
self._close_cookie_dialog()

logger.info(f"Starting search for '{self._search_query}'")
sleep(get_random_sleep(1, 2))
sleep(get_random_sleep(1, 2) * config.behavior.wait_factor)

try:
search_input_box = self._driver.find_element(*self.SEARCH_INPUT)
Expand Down Expand Up @@ -157,7 +157,7 @@ def search_for_ads(
self._check_captcha()

# wait 2 to 3 seconds before checking if results were loaded
sleep(get_random_sleep(2, 3))
sleep(get_random_sleep(2, 3) * config.behavior.wait_factor)

if not self._driver.find_elements(*self.RESULTS_CONTAINER):
self._close_cookie_dialog()
Expand All @@ -167,7 +167,7 @@ def search_for_ads(

# sleep after entering search keyword by randomly selected amount
# between 2 to 3 seconds
sleep(get_random_sleep(2, 3))
sleep(get_random_sleep(2, 3) * config.behavior.wait_factor)

if self._hooks_enabled:
hooks.after_query_sent_hook(self._driver, self._search_query)
Expand Down Expand Up @@ -327,7 +327,7 @@ def _handle_android_click(
click_time = datetime.now().strftime("%H:%M:%S")

# wait a little before starting random actions
sleep(get_random_sleep(2, 3))
sleep(get_random_sleep(2, 3) * config.behavior.wait_factor)

logger.debug(f"Current url on device: {url}")

Expand All @@ -344,12 +344,12 @@ def _handle_android_click(

self._update_click_stats(site_url, click_time, category)

wait_time = self._get_wait_time(is_ad_element)
wait_time = self._get_wait_time(is_ad_element) * config.behavior.wait_factor
logger.debug(f"Waiting {wait_time} seconds on {category.lower()} page...")
sleep(wait_time)

adb_controller.close_browser()
sleep(get_random_sleep(0.5, 1))
sleep(get_random_sleep(0.5, 1) * config.behavior.wait_factor)

def _handle_browser_click(
self,
Expand Down Expand Up @@ -391,7 +391,7 @@ def _handle_browser_click(
self._driver.switch_to.window(window_handle)
click_time = datetime.now().strftime("%H:%M:%S")

sleep(get_random_sleep(3, 5))
sleep(get_random_sleep(3, 5) * config.behavior.wait_factor)
logger.debug(f"Current url on new tab: {self._driver.current_url}")

if self._hooks_enabled and category in ("Ad", "Shopping"):
Expand All @@ -407,7 +407,7 @@ def _handle_browser_click(

self._update_click_stats(url, click_time, category)

wait_time = self._get_wait_time(is_ad_element)
wait_time = self._get_wait_time(is_ad_element) * config.behavior.wait_factor
logger.debug(f"Waiting {wait_time} seconds on {category.lower()} page...")
sleep(wait_time)

Expand All @@ -416,7 +416,7 @@ def _handle_browser_click(

# go back to the original window
self._driver.switch_to.window(original_window_handle)
sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)

def _open_link_in_new_tab(
self, link_element: selenium.webdriver.remote.webelement.WebElement
Expand All @@ -438,7 +438,7 @@ def _open_link_in_new_tab(
actions.key_up(control_command_key)
actions.perform()

sleep(get_random_sleep(0.5, 1))
sleep(get_random_sleep(0.5, 1) * config.behavior.wait_factor)

except JavascriptException as exp:
error_message = str(exp).split("\n")[0]
Expand Down Expand Up @@ -675,7 +675,7 @@ def _get_ad_links(self) -> AdList:
break

self._driver.find_element(By.TAG_NAME, "body").send_keys(Keys.PAGE_DOWN)
sleep(get_random_sleep(2, 2.5))
sleep(get_random_sleep(2, 2.5) * config.behavior.wait_factor)

scroll_count += 1

Expand Down Expand Up @@ -818,7 +818,7 @@ def _close_cookie_dialog(self) -> None:

logger.debug("Waiting for cookie dialog...")

sleep(get_random_sleep(3, 3.5))
sleep(get_random_sleep(3, 3.5) * config.behavior.wait_factor)

all_links = [
element.get_attribute("href")
Expand All @@ -842,9 +842,9 @@ def _close_cookie_dialog(self) -> None:
self._driver.execute_script(
"arguments[0].scrollIntoView(true);", button
)
sleep(get_random_sleep(0.5, 1))
sleep(get_random_sleep(0.5, 1) * config.behavior.wait_factor)
button.click()
sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)

try:
search_input_box = self._driver.find_element(*self.SEARCH_INPUT)
Expand All @@ -864,7 +864,7 @@ def _close_cookie_dialog(self) -> None:
):
pass

sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)
break
else:
logger.debug("No cookie dialog found! Continue with search...")
Expand Down Expand Up @@ -933,7 +933,7 @@ def _make_random_scrolls(self) -> None:
elif direction == Direction.UP:
self._driver.find_element(By.TAG_NAME, "body").send_keys(Keys.PAGE_UP)

sleep(get_random_sleep(1, 3))
sleep(get_random_sleep(1, 3) * config.behavior.wait_factor)

self._driver.find_element(By.TAG_NAME, "body").send_keys(Keys.HOME)

Expand All @@ -956,7 +956,7 @@ def _make_random_swipes(self) -> None:
elif direction == Direction.UP:
self._send_swipe(direction=Direction.UP)

sleep(get_random_sleep(1, 2))
sleep(get_random_sleep(1, 2) * config.behavior.wait_factor)

HOME_KEYCODE = 122
adb_controller.send_keyevent(HOME_KEYCODE) # go to top by sending Home key
Expand Down Expand Up @@ -1059,7 +1059,7 @@ def _make_random_mouse_movements(self) -> None:
def _check_captcha(self) -> None:
"""Check if captcha exists and solve it if 2captcha is used, otherwise exit"""

sleep(get_random_sleep(2, 2.5))
sleep(get_random_sleep(2, 2.5) * config.behavior.wait_factor)

try:
captcha = self._driver.find_element(*self.RECAPTCHA)
Expand Down Expand Up @@ -1106,7 +1106,7 @@ def _check_captcha(self) -> None:
)
self._driver.get(captcha_redirect_url)

sleep(get_random_sleep(2, 2.5))
sleep(get_random_sleep(2, 2.5) * config.behavior.wait_factor)

else:
logger.info("Please try with a different proxy.")
Expand All @@ -1128,18 +1128,18 @@ def _close_choose_location_popup(self) -> None:
logger.debug("Closing location choose dialog...")
estimated_loc_img.click()

sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)

continue_button = self._driver.find_element(*self.LOC_CONTINUE_BUTTON)
logger.debug(continue_button.get_attribute("outerHTML"))

continue_button.click()

sleep(get_random_sleep(0.1, 0.5))
sleep(get_random_sleep(0.1, 0.5) * config.behavior.wait_factor)

except NoSuchElementException:

sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)

try:
logger.debug("Checking alternative location dialog...")
Expand All @@ -1150,7 +1150,7 @@ def _close_choose_location_popup(self) -> None:

not_now_button.click()

sleep(get_random_sleep(0.2, 0.5))
sleep(get_random_sleep(0.2, 0.5) * config.behavior.wait_factor)

except NoSuchElementException:
logger.debug("No location choose dialog seen. Continue to search...")
Expand Down
26 changes: 15 additions & 11 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,12 @@ def get_location(geolocation_db_client: GeolocationDB, proxy: str) -> tuple[floa
if cycle == 1:
break

logger.info("Request will be resend after 60 seconds")
sleep(60)
request_retry_timeout = 60 * config.behavior.wait_factor
logger.info(f"Request will be resend after {request_retry_timeout} seconds")

sleep(get_random_sleep(0.5, 1))
sleep(request_retry_timeout)

sleep(get_random_sleep(0.5, 1) * config.behavior.wait_factor)
else:
ip_address = proxy.split(":")[0]

Expand Down Expand Up @@ -186,7 +188,7 @@ def get_location(geolocation_db_client: GeolocationDB, proxy: str) -> tuple[floa
else:
retry_count = 0
max_retry_count = 5
sleep_seconds = 5
sleep_seconds = 5 * config.behavior.wait_factor

while retry_count < max_retry_count:
try:
Expand Down Expand Up @@ -251,7 +253,7 @@ def get_location(geolocation_db_client: GeolocationDB, proxy: str) -> tuple[floa
sleep(sleep_seconds)
sleep_seconds *= 2

sleep(0.5)
sleep(0.5 * config.behavior.wait_factor)

if latitude and longitude and country_code:
logger.debug(f"Latitude and longitude for {ip_address}: ({latitude}, {longitude})")
Expand Down Expand Up @@ -400,7 +402,8 @@ def solve_recaptcha(
request_retry_count += 1
continue

sleep(15)
initial_captcha_response_wait = 15
sleep(initial_captcha_response_wait * config.behavior.wait_factor)

# check if the CAPTCHA has been solved
response_api_url = "http://2captcha.com/res.php"
Expand Down Expand Up @@ -448,7 +451,7 @@ def take_screenshot(driver: undetected_chromedriver.Chrome) -> None:

if driver:
driver.save_screenshot(filename)
sleep(get_random_sleep(1, 1.5))
sleep(get_random_sleep(1, 1.5) * config.behavior.wait_factor)
logger.info(f"Saved screenshot during exception as {filename}")


Expand Down Expand Up @@ -529,6 +532,7 @@ def _check_error(response_text: str, request_type: str = "in_php") -> tuple[bool
logger.debug("Checking error code...")

error_to_exit, error_to_continue, error_to_break = False, False, False
error_wait = 5 * config.behavior.wait_factor

if request_type == "in_php":
if "ERROR_WRONG_USER_KEY" in response_text or "ERROR_KEY_DOES_NOT_EXIST" in response_text:
Expand All @@ -543,8 +547,8 @@ def _check_error(response_text: str, request_type: str = "in_php") -> tuple[bool
logger.error(
"The queue of your captchas that are not distributed to workers is too long."
)
logger.info("Waiting 5 seconds before sending new request...")
sleep(5)
logger.info(f"Waiting {error_wait} seconds before sending new request...")
sleep(error_wait)

error_to_continue = True

Expand Down Expand Up @@ -572,8 +576,8 @@ def _check_error(response_text: str, request_type: str = "in_php") -> tuple[bool
error_to_exit = True

elif "CAPCHA_NOT_READY" in response_text:
logger.info("Waiting 5 seconds before checking response again...")
sleep(5)
logger.info(f"Waiting {error_wait} seconds before checking response again...")
sleep(error_wait)

error_to_continue = True

Expand Down
Loading

0 comments on commit ff8a13b

Please sign in to comment.