├── __init__.py ├── Consts ├── __init__.py ├── Xpath.py └── Const.py ├── OutLook ├── __init__.py ├── SignInTools │ ├── __init__.py │ ├── AgreeFirstPage.py │ ├── SetPassword.py │ ├── WaitSuccess.py │ ├── InputOtherInformation.py │ ├── InputName.py │ └── InputEmail.py └── OutLook.py ├── .idea ├── sonarlint │ ├── issuestore │ │ └── index.pb │ └── securityhotspotstore │ │ └── index.pb ├── .gitignore ├── codeStyles │ └── codeStyleConfig.xml ├── misc.xml ├── vcs.xml ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── modules.xml ├── AutoOutlook.iml └── webResources.xml ├── resource └── .gitignore ├── README.md ├── .gitattributes ├── browser.py ├── main.py ├── Chrome.py ├── .gitignore └── 未命名绘图.drawio /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Consts/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /OutLook/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/index.pb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.idea/sonarlint/securityhotspotstore/index.pb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resource/.gitignore: -------------------------------------------------------------------------------- 1 | data.txt 2 | phonenum.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoOutlook 2 | 自动实现outlook邮箱注册,验证码手动填入,注册结果写入txt文件中 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /browser.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from Consts import Const 3 | from Chrome import Chrome 4 | 5 | 6 | def get_browser(): 7 | """ doc """ 8 | browser = Chrome(executable_path='msedgedriver.exe') 9 | #browser.delete_all_cookies() 10 | browser.get(Const.URL) 11 | return browser 12 | -------------------------------------------------------------------------------- /OutLook/SignInTools/__init__.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | 3 | from .AgreeFirstPage import AgreeFirstPage 4 | from .InputEmail import InputEmail 5 | from .SetPassword import SetPassword 6 | from .InputName import InputName 7 | from .InputOtherInformation import InputOtherInformation 8 | from .WaitSuccess import WaitSuccess 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/AutoOutlook.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OutLook/SignInTools/AgreeFirstPage.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | import time 3 | 4 | from Consts import Const, Xpath 5 | 6 | 7 | class AgreeFirstPage(object): 8 | """ doc """ 9 | 10 | def __init__(self, browser): 11 | self.browser = browser 12 | 13 | def agree_first_page(self): 14 | self.browser.wait_until_visible(Xpath.NEXT_STEP_BOTTOM).click() 15 | -------------------------------------------------------------------------------- /OutLook/SignInTools/SetPassword.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from Consts import Const, Xpath 3 | 4 | 5 | class SetPassword(object): 6 | """ doc """ 7 | 8 | def __init__(self, browser): 9 | self.browser = browser 10 | self.password = Const.PASSWORD 11 | 12 | def set_password(self): 13 | self.browser.wait_until_visible(Xpath.INPUT_PASSWORD).send_keys(self.password) 14 | self.browser.wait_until_visible(Xpath.NEXT_STEP_BOTTOM).click() 15 | -------------------------------------------------------------------------------- /.idea/webResources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | import os 3 | 4 | from OutLook.OutLook import OutLook 5 | from browser import get_browser 6 | from Consts import Const 7 | 8 | 9 | def main(): 10 | """ 11 | 主函数 12 | :return: 无 13 | """ 14 | outlook = OutLook(get_browser()) 15 | result = outlook.signin() 16 | with open(os.path.abspath("resource/data.txt"), "a") as file: 17 | #print(os.path.abspath("resource/data.txt")) 18 | file.write(result + '\n') 19 | Const.wait(2) 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /OutLook/SignInTools/WaitSuccess.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from selenium.common.exceptions import TimeoutException, NoSuchElementException 3 | from Consts import Const, Xpath 4 | 5 | 6 | class WaitSuccess(object): 7 | """ doc """ 8 | 9 | def __init__(self, browser): 10 | self.browser = browser 11 | 12 | def wait_success(self): 13 | while True: 14 | try: 15 | self.browser.wait_until_visible(Xpath.NO_BOTTOM, 0.5).click() 16 | break 17 | except (TimeoutException, NoSuchElementException): 18 | continue 19 | -------------------------------------------------------------------------------- /Chrome.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from Consts import Const 3 | from selenium import webdriver 4 | from selenium.webdriver.common.by import By 5 | from selenium.webdriver.support.ui import WebDriverWait 6 | from selenium.webdriver.support import expected_conditions as EC 7 | 8 | 9 | class Chrome(webdriver.Edge): 10 | """ doc """ 11 | 12 | def wait_until_visible(self, xpath, max_time = Const.MAX_WAIT_TIME): 13 | """等待指定元素出现并可见.""" 14 | return WebDriverWait(self, max_time).until(EC.visibility_of_element_located((By.XPATH, xpath))) 15 | -------------------------------------------------------------------------------- /Consts/Xpath.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | 3 | 4 | NEXT_STEP_BOTTOM = '//*[@id="iSignupAction"]' 5 | 6 | INPUT_EMAIL_NAME = '//*[@id="MemberName"]' 7 | MEMBER_NAME_ERROR = '//*[@id="MemberNameError"]' 8 | 9 | INPUT_PASSWORD = '//*[@id="PasswordInput"]' 10 | 11 | LAST_NAME = '//*[@id="LastName"]' 12 | FIRST_NAME = '//*[@id="FirstName"]' 13 | 14 | COUNTRY = '//*[@id="Country"]' 15 | BIRTH_YEAR = '//*[@id="BirthYear"]' 16 | BIRTH_MONTH = '//*[@id="BirthMonth"]' 17 | BIRTH_DAY = '//*[@id="BirthDay"]' 18 | 19 | ROBOT_NEXT = '//*[@id="root"]/div/div[1]/button' 20 | PHONE_NUMBER = '//*[@id="wlspispHIPPhoneInput7339b1e5feec4610b72722f103f293cb"]' 21 | SEND_CODE = '//*[@id="wlspispHipSendCodee3f2bfdeb0a54349873ba35a37dc98bd"]' 22 | 23 | KEEP_LOGIN = '//*[@id="lightbox"]/div[3]/div/div[2]/div/div[1]' 24 | NO_BOTTOM = '//*[@id="idBtn_Back"]' 25 | -------------------------------------------------------------------------------- /OutLook/SignInTools/InputOtherInformation.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from Consts import Const, Xpath 3 | from selenium.webdriver.support.select import Select 4 | from random import randint 5 | 6 | 7 | class InputOtherInformation(object): 8 | """ doc """ 9 | def __init__(self, browser): 10 | self.browser = browser 11 | 12 | def input_other_information(self): 13 | Select(self.browser.wait_until_visible(Xpath.COUNTRY)).select_by_value(Const.COUNTRY_VALUE) 14 | self.browser.wait_until_visible(Xpath.BIRTH_YEAR).send_keys( 15 | str(randint(Const.MIN_YEAR, Const.MAX_YEAR)) 16 | ) 17 | self.browser.wait_until_visible(Xpath.BIRTH_MONTH).send_keys( 18 | str(randint(Const.MIN_MONTH, Const.MAX_MONTH)) 19 | ) 20 | self.browser.wait_until_visible(Xpath.BIRTH_DAY).send_keys( 21 | str(randint(Const.MIN_DAY, Const.MAX_DAY)) 22 | ) 23 | self.browser.wait_until_visible(Xpath.NEXT_STEP_BOTTOM).click() 24 | -------------------------------------------------------------------------------- /OutLook/SignInTools/InputName.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | from Consts import Const, Xpath 3 | 4 | 5 | class InputName(object): 6 | """ doc """ 7 | 8 | def __init__(self, browser): 9 | self.browser = browser 10 | self.last_name = str() 11 | self.first_name = str() 12 | 13 | @staticmethod 14 | def random_name_str(): 15 | name_str = str() 16 | name_str += Const.random_char(Const.CAPITALS) 17 | for name_length in range(1, Const.NAME_LENGTH): 18 | name_str += Const.random_char(Const.LOWERCASES) 19 | return name_str 20 | 21 | def random_self_name(self): 22 | self.last_name = self.random_name_str() 23 | self.first_name = self.random_name_str() 24 | 25 | def input_name(self): 26 | self.random_self_name() 27 | self.browser.wait_until_visible(Xpath.LAST_NAME).send_keys(self.last_name) 28 | self.browser.wait_until_visible(Xpath.FIRST_NAME).send_keys(self.first_name) 29 | self.browser.wait_until_visible(Xpath.NEXT_STEP_BOTTOM).click() 30 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 26 | -------------------------------------------------------------------------------- /OutLook/SignInTools/InputEmail.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | import time 3 | 4 | from Consts import Const, Xpath 5 | from selenium.common.exceptions import NoSuchElementException 6 | 7 | 8 | class InputEmail(object): 9 | """ doc """ 10 | 11 | def __init__(self, browser): 12 | self.browser = browser 13 | self.name = str() 14 | 15 | def random_name(self): 16 | name_str = str() 17 | name_str += Const.random_char(Const.LETTER_DICT) 18 | for name_length in range(1, Const.USERNAME_LENGTH): 19 | name_str += Const.random_char(Const.CHAR_DICT) 20 | self.name = name_str 21 | return self.name 22 | 23 | def check_name_error(self): 24 | try: 25 | self.browser.find_element_by_xpath(Xpath.MEMBER_NAME_ERROR) 26 | return False 27 | except NoSuchElementException: 28 | return True 29 | 30 | def input_email_once(self): 31 | self.random_name() 32 | self.browser.wait_until_visible(Xpath.INPUT_EMAIL_NAME).send_keys(self.name) 33 | self.browser.wait_until_visible(Xpath.NEXT_STEP_BOTTOM).click() 34 | Const.wait() 35 | 36 | def input_email(self): 37 | self.input_email_once() 38 | while not self.check_name_error(): 39 | self.input_email_once() 40 | -------------------------------------------------------------------------------- /Consts/Const.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | import time 3 | 4 | from random import randint 5 | 6 | URL = r'https://signup.live.com/' \ 7 | r'signup?' \ 8 | r'lcid=1033&wa=wsignin1.0&rpsnv=13&ct=1680324836&rver=7.0.6737.0&wp=MBI_SSL&' \ 9 | r'wreply=https%3a%2f%2foutlook.live.com%' \ 10 | r'2fowa%2f%3fnlp%3d1%26signup%3d1%26RpsCsrfState%3da3710828-9f15-0e3a-f937-41a93b136105&' \ 11 | r'id=292841&whr=hotmail.com&CBCXT=out&lw=1&fl=dob%2cflname%2cwld&cobrandid=90015&' \ 12 | r'lic=1&uaid=c8ba417cdbac465e9a676c8a30f0b5fa' 13 | CAPITALS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 14 | LOWERCASES = 'abcdefghijklmnopqrstuvwxyz' 15 | NUMBERS = '0123456789' 16 | 17 | LETTER_DICT = CAPITALS + LOWERCASES 18 | CHAR_DICT = CAPITALS + LOWERCASES + NUMBERS 19 | 20 | USERNAME_LENGTH = 10 21 | 22 | PASSWORD = "dkglds_outlook" 23 | 24 | NAME_LENGTH = 5 25 | 26 | COUNTRY_VALUE = 'US' 27 | MIN_YEAR = 1950 28 | MAX_YEAR = 2000 29 | MIN_MONTH = 1 30 | MAX_MONTH = 12 31 | MIN_DAY = 1 32 | MAX_DAY = 28 33 | 34 | with open("resource/phonenum.txt", "r") as file: 35 | PHONE_NUMBER = file.read() 36 | 37 | WAIT_TIME = 0.5 38 | MAX_WAIT_TIME = 10 39 | 40 | 41 | def wait(wait_time=WAIT_TIME): 42 | """ doc """ 43 | time.sleep(wait_time) 44 | 45 | 46 | def random_char(char_dict): 47 | """ doc """ 48 | return char_dict[randint(0, len(char_dict) - 1)] 49 | -------------------------------------------------------------------------------- /OutLook/OutLook.py: -------------------------------------------------------------------------------- 1 | """ doc """ 2 | 3 | from OutLook.SignInTools import \ 4 | AgreeFirstPage, InputEmail, SetPassword, InputName, InputOtherInformation, WaitSuccess 5 | 6 | 7 | class OutLook(object): 8 | """ doc """ 9 | 10 | def __init__(self, browser): 11 | self.browser = browser 12 | self.agree_first_page_tool = None 13 | self.input_email_tool = None 14 | self.set_password_tool = None 15 | self.input_name_tool = None 16 | self.input_other_information_tool = None 17 | self.wait_success_tool = None 18 | self._init_tools() 19 | 20 | def _init_tools(self): 21 | self.agree_first_page_tool = AgreeFirstPage(self.browser) 22 | self.input_email_tool = InputEmail(self.browser) 23 | self.set_password_tool = SetPassword(self.browser) 24 | self.input_name_tool = InputName(self.browser) 25 | self.input_other_information_tool = InputOtherInformation(self.browser) 26 | self.wait_success_tool = WaitSuccess(self.browser) 27 | 28 | def signin(self): 29 | self.agree_first_page_tool.agree_first_page() 30 | self.input_email_tool.input_email() 31 | self.set_password_tool.set_password() 32 | self.input_name_tool.input_name() 33 | self.input_other_information_tool.input_other_information() 34 | print(self.input_email_tool.name + "@outlook.com" + " - " + self.set_password_tool.password) 35 | self.wait_success_tool.wait_success() 36 | return self.input_email_tool.name + "@outlook.com" + " - " + self.set_password_tool.password 37 | 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test.py 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | cover/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | .pybuilder/ 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | # For a library or package, you might want to ignore these files since the code is 89 | # intended to run in multiple environments; otherwise, check them in: 90 | # .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # poetry 100 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 101 | # This is especially recommended for binary packages to ensure reproducibility, and is more 102 | # commonly ignored for libraries. 103 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 104 | #poetry.lock 105 | 106 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 107 | __pypackages__/ 108 | 109 | # Celery stuff 110 | celerybeat-schedule 111 | celerybeat.pid 112 | 113 | # SageMath parsed files 114 | *.sage.py 115 | 116 | # Environments 117 | .env 118 | .venv 119 | env/ 120 | venv/ 121 | ENV/ 122 | env.bak/ 123 | venv.bak/ 124 | 125 | # Spyder project settings 126 | .spyderproject 127 | .spyproject 128 | 129 | # Rope project settings 130 | .ropeproject 131 | 132 | # mkdocs documentation 133 | /site 134 | 135 | # mypy 136 | .mypy_cache/ 137 | .dmypy.json 138 | dmypy.json 139 | 140 | # Pyre type checker 141 | .pyre/ 142 | 143 | # pytype static type analyzer 144 | .pytype/ 145 | 146 | # Cython debug symbols 147 | cython_debug/ 148 | 149 | # PyCharm 150 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 151 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 152 | # and can be added to the global gitignore or merged into this file. For a more nuclear 153 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 154 | #.idea/ 155 | -------------------------------------------------------------------------------- /未命名绘图.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | --------------------------------------------------------------------------------