From 7f6e120db1215c6f5850123378aee6616c0c62d7 Mon Sep 17 00:00:00 2001 From: Konstantinos K <42744293+KonScanner@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:29:02 +0100 Subject: [PATCH] Refactor interia --- .pre-commit-config.yaml | 2 +- requirements.txt | 2 +- sites/interia.py | 250 ++++++++++++++++++++++---------------- sites/tutanota.py | 45 ++++--- utils/Config.py | 47 +++++-- utils/helper_functions.py | 17 ++- 6 files changed, 223 insertions(+), 140 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66d5c74..4a0eac9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: build| dist""" - language_version: python3.9.7 + language_version: python3.10 # flake8 - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/requirements.txt b/requirements.txt index 3388e8b..c64efff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ Faker==9.2.0 selenium==3.141.0 -webdriver-manager==3.5.3 \ No newline at end of file +webdriver-manager \ No newline at end of file diff --git a/sites/interia.py b/sites/interia.py index 1a789fc..d96f213 100644 --- a/sites/interia.py +++ b/sites/interia.py @@ -1,23 +1,32 @@ -from utils.Config import Config +from utils.Config import Config, SleepConfig from selenium import webdriver import time as t -import random -from utils.helper_functions import credential_creator, birthday_creator, write_if_complete +from utils.helper_functions import ( + credential_creator, + birthday_creator, + write_if_complete, +) from selenium.webdriver.common.action_chains import ActionChains -from selenium.webdriver.common.keys import Keys from webdriver_manager.chrome import ChromeDriverManager +from selenium.webdriver.support.ui import Select +import logging +logging.basicConfig(level=logging.INFO) -class Interia: + +class Interia(Config): """ This function is used to register a new email on the Interia website. """ def __init__(self): + Config.__init__(self) + SleepConfig.sleep_amount = 0.15 self.driver = webdriver.Chrome( ChromeDriverManager().install(), options=Config(headless=False).options ) + self.failed_inputs = 0 self.driver.maximize_window() self.e = None (fullname, email, pwd) = credential_creator(fullname=False) @@ -27,126 +36,153 @@ def __init__(self): self.password = pwd self.actions = ActionChains(self.driver) - def _try_click(self, x_path, css=False): - """ - Tries to click on the element with a timer (dirty solution). + @staticmethod + def sleeper(func): + def inner(*args, **kwargs): + result = func(*args, **kwargs) + t.sleep(SleepConfig.sleep_amount) + return result - :param x_path: x_path of element - :param css: True if css element path, False if x_path. Default: False - """ - state = True - for _ in range(6): - if state: - try: - if not css: - self.driver.find_element_by_xpath(x_path).click() - else: - self.driver.find_element_by_css_selector(x_path).click() - t.sleep(1) - state = False - print(state) - except Exception as e: - self.e = e - t.sleep(1.5) - print(self.e) - - def _select_month(self): - """ - Selects the month element and populates it. - """ - keytaps = "".join([".key_down(Keys.DOWN)" for _ in range(self.month)]) - eval(f"self.actions{keytaps}.send_keys(Keys.ENTER).perform()") + return inner - def _select_clear(self): - """ - Selects the clear element. - """ - keytaps = "".join([".key_down(Keys.BACKSPACE)" for _ in range(100)]) - eval(f"self.actions{keytaps}.perform()") + @sleeper + def __deal_with_cookies(self): + cookies = self.driver.find_element_by_xpath("/html/body/div[3]/div[2]/button[3]") + self.force_click(cookies) - def _select_gender(self): - """ - Selects the gender of the email. - """ - keytaps = "".join( - [".key_down(Keys.DOWN)" for _ in range(random.randint(1, 2))] + @sleeper + def __deal_with_name(self): + name = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[1]/input" ) + name.send_keys(self.first) - eval(f"self.actions{keytaps}.send_keys(Keys.ENTER).perform()") + @sleeper + def __deal_with_surname(self): + surname = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[2]/input" + ) + surname.send_keys(self.last) - def _create(self): - """ - Creates the email. - """ - self.driver.get("https://konto-pocztowe.interia.pl/#/nowe-konto/darmowe") - t.sleep(0.55) - self._try_click("/html/body/div[3]/div[2]/button[3]") - # Pass in input + @sleeper + def __deal_with_username(self): + username = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[5]/div[1]/input" + ) + username.send_keys(self.username) - self.driver.find_element_by_xpath( - "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[1]/input" - ).send_keys(self.first) - t.sleep(0.3) - self.driver.find_element_by_xpath( - "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[2]/input" - ).send_keys(self.last) - t.sleep(0.3) - # Day of birth - self.driver.find_element_by_xpath( + @sleeper + def __deal_with_day(self): + day = self.driver.find_element_by_xpath( "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[3]/div[1]/input" - ).send_keys(self.day) - t.sleep(0.3) - # Day of month - self._try_click( - "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[3]/div[2]/div[2]" ) - self._select_month() - t.sleep(0.3) - # Day of Year - self.driver.find_element_by_xpath( + day.send_keys(self.day) + + @sleeper + def __deal_with_month(self): + dropdown = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[3]/div[2]" + ) + self.force_click(dropdown) + options = self.driver.find_element_by_class_name("account-select__options") + first_item = options.find_element_by_class_name("account-select__options__item") + self.force_click(first_item) + + @sleeper + def __deal_with_year(self): + year = self.driver.find_element_by_xpath( "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[3]/div[3]/input" - ).send_keys(self.year) - t.sleep(0.3) - self._try_click("/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[4]/div[2]") - self._select_gender() - username_tag = ( - "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[5]/div[1]/input" ) - self.driver.find_element_by_xpath(username_tag).click() - self._select_clear() - t.sleep(0.3) - self.driver.find_element_by_xpath(username_tag).send_keys(self.username) - t.sleep(0.3) + year.send_keys(self.year) - self.driver.find_element_by_xpath( + @sleeper + def __deal_with_pass1(self): + pass_1 = self.driver.find_element_by_xpath( "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[6]/div/input" - ).send_keys(self.password) - t.sleep(0.3) + ) + pass_1.send_keys(self.password) - self.driver.find_element_by_xpath( + @sleeper + def __deal_with_pass2(self): + pass_2 = self.driver.find_element_by_xpath( "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[7]/div/input" - ).send_keys(self.password) - t.sleep(0.3) - self._try_click( - "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[2]/div[1]/div[1]/label" ) - t.sleep(0.3) - t.sleep(5) - self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") + pass_2.send_keys(self.password) - # Create account btn - self._try_click("/html/body/div[1]/div/div/div/div/div[2]/div/form/div[2]/button") - t.sleep(0.55) - self._try_click("/html/body/div[2]/div[3]/div/div[2]/div[1]") - self._try_click( - "/html/body/div[2]/section[3]/div[1]/div[1]/section/ul/li/div[2]/div[1]/div[1]/span" + def __deal_with_passwords(self): + self.__deal_with_pass1() + self.__deal_with_pass2() + + @sleeper + def __deal_with_gender(self): + dropdown = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div[4]/div[1]" + ) + self.force_click(dropdown) + options = self.driver.find_element_by_class_name("account-select__options") + first_item = options.find_element_by_class_name("account-select__options__item") + self.force_click(first_item) + + @sleeper + def __remove_gambling_ads(self): + gambling_ads = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[2]/div[1]/div[2]/div[4]/label" + ) + self.force_click(gambling_ads) + + @sleeper + def __accept_bad_conditions(self): + conditions = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[2]/div[1]/div[1]/label/div/div" ) - self._try_click("/html/body/div[2]/section[4]/div/div/div[1]/div/div/span/div") - self._try_click("/html/body/div[2]/section[4]/div/div/div[2]/div/a[2]") - print("Was the account successfully created?") - response = input() - if response == "y": + self.force_click(conditions) + self.__remove_gambling_ads() + + @sleeper + def __finalize_account_creation(self): + create_account = self.driver.find_element_by_xpath( + "/html/body/div[1]/div/div/div/div/div[2]/div/form/div[2]/button" + ) + self.force_click(create_account) + t.sleep(2) + + @sleeper + def __account_created(self): + logging.warning("Has the account been created?") + s = input("[y/N]: ").lower() + if s == "y": write_if_complete( - email=self.username, password=self.password, domain="interia", country="pl" + email=self.username, + password=self.password, + domain="interia", + country="pl", ) + elif s == "n": + self.failed_inputs += 1 + logging.error("Account was not successfully created, please try again.") + else: + logging.error("The answer provided is not y or n! PLEASE INSERT CORRECT ANSWER...") + if self.failed_inputs < 3: + self.__account_created() + else: + raise ValueError("The answer provided was not y or n!!!") + + def _create(self): + """ + Creates the email. + """ + self.driver.get("https://konto-pocztowe.interia.pl/#/nowe-konto/darmowe") + t.sleep(0.55) + self.__deal_with_cookies() + self.__deal_with_name() + self.__deal_with_surname() + self.__deal_with_username() + self.__deal_with_day() + self.__deal_with_month() + self.__deal_with_year() + self.__deal_with_passwords() + self.__deal_with_gender() + self.__accept_bad_conditions() + self.__finalize_account_creation() + self.__account_created() self.driver.quit() diff --git a/sites/tutanota.py b/sites/tutanota.py index b310b63..e48eb02 100644 --- a/sites/tutanota.py +++ b/sites/tutanota.py @@ -2,9 +2,10 @@ from selenium import webdriver import time as t from utils.helper_functions import credential_creator, write_if_complete -from selenium.webdriver.common.action_chains import ActionChains -from selenium.webdriver.common.keys import Keys from webdriver_manager.chrome import ChromeDriverManager +import logging + +logging.basicConfig(level=logging.INFO) class TutaAccounts: @@ -23,13 +24,15 @@ def __init__(self): self.username = email self.password = pwd - def _try_click(self, x_path, css=False): + def _try_click(self, x_path, css=False, prompt=""): """ Tries to click on the element with a timer (dirty solution). :param x_path: x_path of element :param css: True if css element path, False if x_path. Default: False """ + if prompt != "": + logging.info(f"[ACTION]: {prompt}") state = True for _ in range(6): if state: @@ -44,20 +47,27 @@ def _try_click(self, x_path, css=False): except Exception as e: self.e = e t.sleep(1.5) - print(self.e) + logging.error(f"Failed to click with exception {self.e}") def _create(self): """ Creates the email. """ + # Load site self.driver.get("https://mail.tutanota.com/login") - self._try_click("/html/body/div/div[3]/div[2]/div/div[3]/div/button") - self._try_click("/html/body/div/div[3]/div[2]/div/div[4]/div/div/div/button[1]") + + # Click Sign-up self._try_click( - "#upgrade-account-dialog > div.flex.center-horizontally.wrap > div:nth-child(1) >" - " div.buyOptionBox > div.button-min-height > button > div", - css=True, + "/html/body/div/div[3]/div[2]/div/div[1]/div[2]/button[1]/div/div", + prompt="Click Sign-up", + ) + + # Free version + self._try_click( + "/html/body/div/div[2]/div/div/div/div/div/div[2]/div/div/div[2]/div/div[3]/div[1]/div/div[1]/div[5]/button/div" ) + + # Checkboxes self._try_click( "#modal > div:nth-child(2) > div > div > div > div:nth-child(2) > div:nth-child(1) >" " div > input[type=checkbox]", @@ -76,19 +86,24 @@ def _create(self): ) t.sleep(0.55) # Pass in input + + # Pass in username self.driver.find_element_by_css_selector( "#signup-account-dialog > div > div.text-field.rel.overflow-hidden.text.pt > div > div" " > div > div.flex-grow.rel > input" ).send_keys(self.username) - t.sleep(0.05) + t.sleep(0.15) + + # Pass in password self.driver.find_element_by_css_selector( "#signup-account-dialog > div > div:nth-child(2) > div:nth-child(1) > div > div > div >" " div.flex-grow.rel > input.input" ).send_keys(self.password) - t.sleep(0.05) + t.sleep(0.15) + + # Pass in repeat password self.driver.find_element_by_css_selector( - "#signup-account-dialog > div > div:nth-child(2) > div:nth-child(3) > div > div > div >" - " div > input" + "#signup-account-dialog > div > div:nth-child(2) > div:nth-child(2) > div > div > div > div.flex-grow.rel > input" ).send_keys(self.password) t.sleep(0.15) self._try_click( @@ -101,8 +116,8 @@ def _create(self): self._try_click( "/html/body/div/div[2]/div/div/div/div/div/div[2]/div/div/div[2]/div/div[5]/button" ) - response = input("Was the account successfully created?") + response = input("Was the account successfully created? [y/n] ") - if response == "y": + if response.lower() == "y": write_if_complete(email=self.username, password=self.password, domain="tutanota") self.driver.quit() diff --git a/utils/Config.py b/utils/Config.py index b190968..0dd9e10 100644 --- a/utils/Config.py +++ b/utils/Config.py @@ -1,8 +1,13 @@ from selenium import webdriver +from time import sleep +import logging -class Config: +class SleepConfig: + sleep_amount = 0.1 + +class Config: """ The config class is used to set the browser options. @@ -14,14 +19,42 @@ def __init__(self, headless: bool = True) -> None: self.options = webdriver.ChromeOptions() if headless: self.options.headless = True - self.options.add_argument(f'user-agent={user_agent}') + self.options.add_argument(f"user-agent={user_agent}") self.options.add_argument("--window-size=1920,1080") - self.options.add_argument('--ignore-certificate-errors') - self.options.add_argument('--allow-running-insecure-content') + self.options.add_argument("--ignore-certificate-errors") + self.options.add_argument("--allow-running-insecure-content") self.options.add_argument("--disable-extensions") self.options.add_argument("--proxy-server='direct://'") self.options.add_argument("--proxy-bypass-list=*") self.options.add_argument("--start-maximized") - self.options.add_argument('--disable-gpu') - self.options.add_argument('--disable-dev-shm-usage') - self.options.add_argument('--no-sandbox') + self.options.add_argument("--disable-gpu") + self.options.add_argument("--disable-dev-shm-usage") + self.options.add_argument("--no-sandbox") + self.sleep_amount = 0.1 + + @staticmethod + def force_click(element, sleep_amount=None): + """ + Clicks something until it works + + :param element: The element to click on + :param sleep_time: How many time to wait between clicks + """ + while True: + try: + element.click() + return + except Exception as e: + logging.debug(f"Forcing click with exception {e}") + sleep_amount = sleep_amount if sleep_amount else SleepConfig.sleep_amount + sleep(sleep_amount) + + @staticmethod + def debug_html(element): + """ + Provides full outterHTML of element, for debugging + + :param element: The element to extract the outterHTML from + """ + if element: + logging.info(element.get_attribute("outerHTML")) diff --git a/utils/helper_functions.py b/utils/helper_functions.py index 34f6995..71e08b8 100644 --- a/utils/helper_functions.py +++ b/utils/helper_functions.py @@ -1,11 +1,9 @@ import random import hashlib from faker import Faker -import re import os -import random -user_path = None # Give it a safe place to store and update your accounts.txt file +USER_PATH = os.getcwd() # Give it a safe place to store and update your accounts.txt file def credential_creator(fullname=False): @@ -21,9 +19,9 @@ def credential_creator(fullname=False): email = fullname.replace(" ", "") + str(integer_ran) password = ( - hashlib.sha224( - b"Nobody inspects the spammish repetition" + bytes(integer_ran) - ).hexdigest()[:12] + hashlib.sha256(b"Nobody inspects the spammish repetition" + bytes(integer_ran)).hexdigest()[ + :12 + ] + "!" ) @@ -43,7 +41,9 @@ def birthday_creator(): return day, month, year -def write_if_complete(email: str, password: str, domain: str, country="com") -> None: +def write_if_complete( + email: str, password: str, domain: str, country="com", user_path: str = USER_PATH +) -> None: """ Writes file to disk if the user deems the creation is complete. @@ -55,7 +55,6 @@ def write_if_complete(email: str, password: str, domain: str, country="com") -> :rtpye: [None] """ - if user_path is None: - user_path = os.getcwd() + user_path = os.getcwd() if user_path is None else USER_PATH with open(f"{user_path}/accounts.txt", "a+") as f: f.write(f"{email}@{domain}.{country}:{password}\n")