├── .gitignore ├── .gitattributes ├── demo.gif ├── README.md ├── requirements.txt └── puzzle_solver.py /.gitignore: -------------------------------------------------------------------------------- 1 | temp/ 2 | *.png 3 | *.exe 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no-name-user-name/tiktok-puzzle-captcha-solver/HEAD/demo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tiktok-puzzle-captcha-solver 2 | 3 | Used chromedriver + opencv 4 | 5 | ![image](https://github.com/no-name-user-name/tiktok-puzzle-captcha-solver/blob/main/demo.gif) 6 | 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Automatically generated by https://github.com/damnever/pigar. 2 | 3 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 11 4 | matplotlib == 3.5.1 5 | 6 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 6 7 | numpy == 1.21.4 8 | 9 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 5 10 | opencv_python == 4.5.5.62 11 | 12 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 14,15 13 | selenium == 4.0.0.b4 14 | 15 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 16 16 | selenium_move_cursor == 0.0.8 17 | 18 | # C:\Users\dimaz\Desktop\work\tiktok\puzzle_solver.py: 13 19 | undetected_chromedriver == 3.0.6 20 | -------------------------------------------------------------------------------- /puzzle_solver.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | import math 5 | import cv2 as cv 6 | import numpy as np 7 | import urllib.request 8 | from time import sleep 9 | from pprint import pprint 10 | from collections import Counter 11 | from matplotlib import pyplot as plt 12 | 13 | import undetected_chromedriver as uc 14 | from selenium.webdriver.common.by import By 15 | from selenium.webdriver.common.action_chains import ActionChains 16 | from selenium_move_cursor.MouseActions import move_to_element_chrome 17 | 18 | class TikTok(): 19 | def __init__(self,profile): 20 | self.options = uc.ChromeOptions() 21 | prof_id = profile 22 | path = f'temp/profile{prof_id}' 23 | self.options.add_argument(f'--user-data-dir={os.path.abspath(path)}') 24 | self.options.add_argument('--no-first-run --no-service-autorun --password-store=basic') 25 | self.options.add_argument("--window-size=1920,1080") 26 | self.options.add_argument("--disable-popup-blocking") 27 | self.options.page_load_strategy = 'eager' 28 | self.options.add_argument('--disable-gpu') 29 | 30 | def start_chrome(self): 31 | self.driver = uc.Chrome(options=self.options) 32 | self.driver.maximize_window() 33 | self.driver.implicitly_wait(5) 34 | 35 | def login(self,username,password): 36 | self.start_chrome() 37 | 38 | self.driver.get('https://www.tiktok.com/login/phone-or-email/email') 39 | 40 | try: 41 | self.driver.find_element(By.NAME,'email').send_keys(username) 42 | self.driver.find_element(By.NAME,'password').send_keys(password) 43 | self.driver.find_element(By.CSS_SELECTOR,'button[type="submit"]').click() 44 | except: 45 | pass 46 | 47 | try: 48 | self.driver.find_element(By.ID,"captcha-verify-image") 49 | while 1: 50 | ans = self.solve_captcha() 51 | if ans['success']: 52 | break 53 | sleep(4) 54 | except Exception as e: 55 | pass 56 | 57 | def solve_captcha(self): 58 | captcha = self.driver.find_element(By.ID,"login_slide") 59 | print('wait img loader...') 60 | while 1: 61 | try: 62 | img = self.driver.find_element(By.ID,"captcha-verify-image") 63 | if img.get_attribute('src'): 64 | sleep(1) 65 | img.screenshot('foo.png') 66 | break 67 | except Exception as e: 68 | print('wait img loader.....') 69 | try: 70 | self.driver.find_element(By.XPATH,"//div[contains(text(), 'Authorize')]") 71 | return {'success':1} 72 | except Exception as e: 73 | raise e 74 | 75 | img = cv.imread('foo.png') 76 | gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) 77 | corners = cv.goodFeaturesToTrack(gray,15,0.05,1) 78 | corners = np.int0(corners) 79 | 80 | x_Array = [] 81 | for i in corners: 82 | x,y = i.ravel() 83 | cv.circle(img,(x,y),3,255,-1) 84 | if x > 70: 85 | x_Array.append(x) 86 | 87 | x_Array.sort() 88 | print(x_Array) 89 | 90 | slider = self.driver.find_element(By.CLASS_NAME,"captcha_verify_slide--slidebar") 91 | source = self.driver.find_element(By.CLASS_NAME,"secsdk-captcha-drag-icon") 92 | source_location = source.location 93 | source_size = source.size 94 | 95 | array = [170, 345, 400, 400, 345] 96 | unic = Counter(x_Array) # проверка числа на уникальность, для устранения "гуляюших координат" 97 | for x in x_Array: 98 | if unic[x] > 1: 99 | x_offset = x-8 100 | break 101 | 102 | y_offset = 0 103 | action = ActionChains(self.driver) 104 | try: 105 | steps_count = 5 106 | step = (x_offset)/steps_count 107 | act_1 = action.click_and_hold(source) 108 | for x in range(0,steps_count): 109 | act_1.move_by_offset(step, y_offset) 110 | act_1.release().perform() 111 | 112 | msg = self.driver.find_element(By.CLASS_NAME,'msg').find_element(By.TAG_NAME,'div').text 113 | while msg == '': 114 | msg = self.driver.find_element(By.CLASS_NAME,'msg').find_element(By.TAG_NAME,'div').text 115 | print(msg) 116 | 117 | if 'Верификация пройдена' in msg or 'complete' in msg: 118 | return {'success':1} 119 | else: 120 | return {'success':0} 121 | 122 | except Exception as e: 123 | print(e) 124 | 125 | def close_browser(self): 126 | self.driver.quit() 127 | 128 | 129 | if __name__ == '__main__': 130 | try: 131 | email = 'pupkin@gmail.com' 132 | password = '@password' 133 | 134 | t = TikTok('new1') 135 | t.login(email, password) 136 | sleep(10) 137 | 138 | except Exception as e: 139 | raise e 140 | finally: 141 | try: 142 | t.close_browser() 143 | except: 144 | pass 145 | 146 | 147 | --------------------------------------------------------------------------------