├── requirements.txt ├── colorize.py ├── main.py ├── proxier.py ├── README.md └── api.py /requirements.txt: -------------------------------------------------------------------------------- 1 | colored==1.4.4 2 | pydub==0.25.1 3 | requests==2.28.1 4 | SpeechRecognition==3.9.0 5 | undetected_chromedriver==3.5.4 6 | user_agent==0.1.10 -------------------------------------------------------------------------------- /colorize.py: -------------------------------------------------------------------------------- 1 | from colored import attr, fg 2 | 3 | 4 | class Colors: 5 | yellow = fg('yellow') 6 | white = fg('white') 7 | blue = fg('blue_3b') 8 | dblue = fg('dodger_blue_2') 9 | cyan = fg('cyan') 10 | green = fg('green_1') 11 | sgreen = fg('medium_spring_green') 12 | red = fg('red') 13 | purple = fg('purple_1a') 14 | magenta = fg('magenta') 15 | grey = fg('grey_27') 16 | orange = fg('orange_red_1') 17 | bold = attr('bold') 18 | reset = attr('reset') 19 | 20 | INFO = f'{yellow}[INFO]{reset}' 21 | WARNING = f'{orange}[WARNING]{reset}' 22 | PROXY = f'{cyan}[PROXY]{reset}' 23 | SUCCESS = f'{green}[SUCCESS]{reset}' 24 | FAILED = f'{red}[FAILED]{reset}' 25 | 26 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from api import RecaptchaBypass 4 | 5 | if __name__ == '__main__': 6 | # Clearing the console screen (works on both Windows and Unix-like systems) 7 | os.system('cls' if os.name == 'nt' else 'clear') 8 | 9 | # For demonstration purposes only (no need to write it like I did) 10 | debug = True 11 | headless = False 12 | use_proxy = True 13 | use_agent = False 14 | 15 | # Optional: Set to True to check IP information if using a proxy 16 | ip_info = True 17 | 18 | # URL for the Recaptcha demo 19 | demo_url = 'https://www.google.com/recaptcha/api2/demo' 20 | 21 | # By default, all options are set to False; set to True directly if needed. 22 | bypass_instance = RecaptchaBypass(debug=debug, headless=headless, use_proxy=use_proxy, use_agent=use_agent) 23 | 24 | if ip_info: 25 | # Optional: Check IP information if using a proxy 26 | bypass_instance.check_ip() 27 | else: 28 | # Bypass the Recaptcha v2 on the demo URL 29 | bypass_instance.bypass_recaptcha_v2(demo_url) 30 | -------------------------------------------------------------------------------- /proxier.py: -------------------------------------------------------------------------------- 1 | import re 2 | from concurrent.futures import ThreadPoolExecutor 3 | from random import choice, shuffle 4 | from threading import Event, Lock 5 | 6 | import requests 7 | 8 | from colorize import Colors 9 | 10 | 11 | class Proxier: 12 | PROXY_URL = 'https://free-proxy-list.net/' 13 | CHECK_URL = 'https://www.bing.com' 14 | MAX_WORKERS = 50 15 | TIMEOUT = 10 16 | 17 | def __init__(self): 18 | self.session = requests.Session() 19 | self.live_proxies = set() 20 | self.lock = Lock() 21 | self.event = Event() 22 | self._start_checking() 23 | 24 | def __del__(self): 25 | self.session.close() 26 | 27 | @property 28 | def live_proxy(self): 29 | if self.live_proxies: 30 | return choice(list(self.live_proxies)) 31 | exit(f'{Colors.FAILED} No Live Proxy found!') 32 | 33 | @staticmethod 34 | def _search_proxies(response): 35 | pattern = re.compile(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+\b') 36 | return [f'http://{proxy}' for proxy in pattern.findall(response.text)] 37 | 38 | def fetch_proxies(self): 39 | try: 40 | response = self.session.get(self.PROXY_URL) 41 | response.raise_for_status() 42 | proxies = self._search_proxies(response) 43 | shuffle(proxies) 44 | return list(set(proxies)) 45 | except Exception as exc: 46 | print(Colors.FAILED, str(exc)) 47 | 48 | def _check_proxy(self, proxy: str): 49 | if self.event.is_set(): 50 | return 51 | try: 52 | proxies = {'http': proxy, 'https': proxy} 53 | response = self.session.get(self.CHECK_URL, proxies=proxies, timeout=self.TIMEOUT) 54 | if 200 <= response.status_code <= 299: 55 | with self.lock: 56 | print(f'{Colors.PROXY} {proxy} - {Colors.green}Live!{Colors.reset}') 57 | self.live_proxies.add(proxy) 58 | self.event.set() 59 | return proxy 60 | 61 | except requests.RequestException: 62 | with self.lock: 63 | if not self.event.is_set(): 64 | print(f'{Colors.PROXY} {proxy} - {Colors.red}Dead!{Colors.reset}') 65 | 66 | def _start_checking(self): 67 | proxies = self.fetch_proxies() 68 | if proxies: 69 | print(f'\n📍 Scraped {Colors.yellow}{len(proxies)}{Colors.reset} Proxies\n') 70 | with ThreadPoolExecutor(max_workers=self.MAX_WORKERS) as executor: 71 | for proxy in proxies: 72 | executor.submit(self._check_proxy, proxy) 73 | if self.event.is_set(): 74 | break -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # Google Recaptcha v2 4 | 5 | **BypassV2** tool for bypassing google recaptcha v2 using `undetected-chromedriver`. 6 | 7 | 8 | 9 |
10 | 11 | ## Installation 12 | 13 | To use _**BypassV2**_, open your terminal and navigate to the folder that contains _**BypassV2**_ content :: 14 | 15 | ``` 16 | pip install -r requirements.txt 17 | ``` 18 | 19 | ## Parameters (boolean) 20 | 21 | ``` 22 | debug (For debugging information) 23 | headless (For headless mode) - Not recommended because sometimes it will get blocked. 24 | use_proxy (Use a proxy) - Very fast checking (Concurrent) 25 | use_agent (Use a custom user agent) 26 | ``` 27 | 28 | ## Without Proxy 29 | 30 | ```python 31 | import os 32 | 33 | from api import RecaptchaBypass 34 | 35 | 36 | os.system('cls' if os.name == 'nt' else 'clear') 37 | 38 | demo_url = 'https://www.google.com/recaptcha/api2/demo' 39 | 40 | bypass_instance = RecaptchaBypass() 41 | bypass_instance.bypass_recaptcha_v2(demo_url) 42 | ``` 43 | 44 | 45 | 46 | ## Without Proxy + Debug 47 | 48 | ```python 49 | import os 50 | 51 | from api import RecaptchaBypass 52 | 53 | 54 | os.system('cls' if os.name == 'nt' else 'clear') 55 | 56 | demo_url = 'https://www.google.com/recaptcha/api2/demo' 57 | 58 | bypass_instance = RecaptchaBypass(debug=True) 59 | bypass_instance.bypass_recaptcha_v2(demo_url) 60 | ``` 61 | 62 | 63 | 64 | ## Using Proxy + Bypassing 65 | 66 | > Not all proxies are working; some of them will get blocked. 67 | 68 | ```python 69 | import os 70 | 71 | from api import RecaptchaBypass 72 | 73 | 74 | os.system('cls' if os.name == 'nt' else 'clear') 75 | 76 | demo_url = 'https://www.google.com/recaptcha/api2/demo' 77 | 78 | bypass_instance = RecaptchaBypass(use_proxy=True) 79 | bypass_instance.bypass_recaptcha_v2(demo_url) 80 | ``` 81 | 82 | 83 | 84 | ## Using Proxy + Check IP 85 | 86 | ```python 87 | import os 88 | 89 | from api import RecaptchaBypass 90 | 91 | 92 | os.system('cls' if os.name == 'nt' else 'clear') 93 | 94 | demo_url = 'https://www.google.com/recaptcha/api2/demo' 95 | 96 | bypass_instance = RecaptchaBypass(use_proxy=True) 97 | bypass_instance.check_ip() 98 | ``` 99 | 100 | 101 | 102 | ## Legal Disclaimer 103 | 104 | > **Note** 105 | > This was made for educational purposes only, nobody which directly involved in this project is responsible for any damages caused. **_You are responsible for your actions._** 106 | -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from random import uniform 4 | from time import sleep 5 | from urllib.request import urlretrieve 6 | 7 | import undetected_chromedriver as uc 8 | from pydub import AudioSegment 9 | from selenium.common.exceptions import NoSuchElementException, TimeoutException 10 | from selenium.webdriver.common.by import By 11 | from selenium.webdriver.common.keys import Keys 12 | from selenium.webdriver.support.expected_conditions import \ 13 | presence_of_element_located as poel 14 | from selenium.webdriver.support.ui import WebDriverWait 15 | from speech_recognition import AudioFile, Recognizer 16 | from user_agent import generate_user_agent 17 | 18 | from colorize import Colors 19 | from proxier import Proxier 20 | 21 | 22 | class RecaptchaBypass: 23 | def __init__(self, debug=False, use_proxy=False, use_agent=False, headless=False): 24 | self.debug = debug 25 | self.browser = self._get_chromedriver(use_proxy, use_agent, headless) 26 | self.wait = WebDriverWait(self.browser, 10) 27 | 28 | def _get_chromedriver(self, use_proxy, use_agent, headless): 29 | chrome_options = uc.ChromeOptions() 30 | chrome_options.add_argument('--disable-blink-features=AutomationControlled') 31 | chrome_options.add_argument('--disable-extensions') 32 | chrome_options.add_argument('--disable-gpu') 33 | chrome_options.add_argument('--disable-dev-shm-usage') 34 | chrome_options.add_argument('--no-sandbox') 35 | if use_proxy: 36 | working_proxy = self._setup_proxy() 37 | self._print_message('\n' + Colors.INFO, f'{Colors.purple}Live Proxy {Colors.red}>{Colors.reset} {working_proxy}') 38 | chrome_options.add_argument(f'--proxy-server={working_proxy}') 39 | if use_agent: 40 | ua = generate_user_agent() 41 | self._print_message(Colors.INFO, f'{Colors.purple}User Agent {Colors.red}>{Colors.reset} {ua}') 42 | chrome_options.add_argument(f'--user-agent={ua}') 43 | if headless: 44 | chrome_options.add_argument('--headless') 45 | browser = uc.Chrome(options=chrome_options) 46 | browser.maximize_window() 47 | return browser 48 | 49 | def _print_message(self, level, message): 50 | print(f'{level} {message}') 51 | 52 | def _handle_exception(self, exc): 53 | block = self._is_block() 54 | if block: 55 | self._print_message(Colors.WARNING, f'IP has been blocked! {block.text}') 56 | else: 57 | self._print_message(Colors.FAILED, type(exc).__name__) 58 | self._quit_browser() 59 | 60 | def _quit_browser(self): 61 | self.browser.quit() 62 | self._is_debug('Browser closed!\n') 63 | 64 | def _setup_proxy(self): 65 | proxy = Proxier() 66 | return proxy.live_proxy 67 | 68 | def check_ip(self): 69 | """This is for checking IP only""" 70 | try: 71 | self._print_message(Colors.INFO, f'{Colors.blue}Checking IP information..{Colors.reset}') 72 | self.browser.get('https://ipwho.is') 73 | sleep(uniform(2, 3)) 74 | pre_element = self.browser.find_element(By.TAG_NAME, 'pre') 75 | json_data = pre_element.text 76 | data_dict = json.loads(json_data) 77 | self._print_message(Colors.SUCCESS, f'{Colors.white}{data_dict["ip"]}{Colors.reset} ({data_dict["country"]})') 78 | self._quit_browser() 79 | except (TimeoutException, NoSuchElementException, Exception) as exc: 80 | self._handle_exception(exc) 81 | 82 | def bypass_recaptcha_v2(self, url): 83 | """Bypassing google recaptcha v2""" 84 | try: 85 | self._get_source(url) 86 | self._click_recaptcha_checkbox() 87 | self._click_audio_button() 88 | audio_url = self._get_audio_url() 89 | self._transcribe_audio(audio_url) 90 | self._click_demo_submit() 91 | self._quit_browser() 92 | except (TimeoutException, NoSuchElementException, Exception) as exc: 93 | self._handle_exception(exc) 94 | 95 | def _get_source(self, url): 96 | self._print_message(Colors.INFO, f'{Colors.blue}Initiating v2 bypass..{Colors.reset}') 97 | self.browser.get(url) 98 | sleep(uniform(2, 3)) 99 | 100 | def _is_block(self): 101 | try: 102 | recaptcha_header = self.browser.find_element(By.CLASS_NAME, 'rc-doscaptcha-body-text') 103 | return recaptcha_header 104 | except NoSuchElementException: 105 | return None 106 | 107 | def _is_debug(self, message): 108 | if self.debug: 109 | self._print_message(Colors.INFO, f'{Colors.white}{message}{Colors.reset}') 110 | 111 | def _click_recaptcha_checkbox(self): 112 | self._is_debug('Getting recaptcha checkbox..') 113 | recaptcha_frame = self.browser.find_element(By.TAG_NAME, 'iframe') 114 | anchor_url = recaptcha_frame.get_attribute('src') 115 | self._print_message(Colors.INFO, f'{Colors.purple}Anchor URL {Colors.red}>{Colors.reset} {anchor_url}') 116 | self.browser.switch_to.frame(recaptcha_frame) 117 | check_box = self.wait.until(poel((By.CSS_SELECTOR, "#recaptcha-anchor"))) 118 | self._is_debug('Clicking checkbox..') 119 | check_box.click() 120 | self.browser.switch_to.default_content() 121 | 122 | def _click_audio_button(self): 123 | self._is_debug('Getting recaptcha challenge..') 124 | captcha_challenge = self.browser.find_elements(By.TAG_NAME, 'iframe')[2] 125 | captcha_challenge_url = captcha_challenge.get_attribute('src') 126 | self._print_message(Colors.INFO, f'{Colors.purple}Bframe URL {Colors.red}>{Colors.reset} {captcha_challenge_url}') 127 | self.browser.switch_to.frame(captcha_challenge) 128 | audio_button = self.wait.until(poel((By.CSS_SELECTOR, '#recaptcha-audio-button'))) 129 | self._is_debug('Clicking audio button..') 130 | audio_button.click() 131 | self.browser.switch_to.default_content() 132 | 133 | def _get_audio_url(self): 134 | self.browser.switch_to.frame(self.browser.find_elements(By.TAG_NAME, 'iframe')[2]) 135 | download_button = self.wait.until(poel((By.CSS_SELECTOR, '.rc-audiochallenge-tdownload-link'))) 136 | self._is_debug('Clicking download button..') 137 | audio_url = download_button.get_attribute('href') 138 | self._print_message(Colors.INFO, f'{Colors.purple}Audio URL {Colors.red}>{Colors.reset} {audio_url}') 139 | return audio_url 140 | 141 | def _transcribe_audio(self, audio_url): 142 | phrase_text, wav_output = self._audio_to_text(audio_url) 143 | self._print_message(Colors.INFO, f'{Colors.purple}Phrase Text {Colors.red}> {Colors.green}{phrase_text}{Colors.reset}') 144 | text_field = self.wait.until(poel((By.CSS_SELECTOR, '#audio-response'))) 145 | text_field.send_keys(phrase_text, Keys.ENTER) 146 | self._is_debug('Entering the phrase text..') 147 | self.browser.switch_to.default_content() 148 | os.remove(wav_output) 149 | 150 | def _audio_to_text(self, audio_url): 151 | filename = 'audio.mp3' 152 | wav_output = 'audio.wav' 153 | urlretrieve(audio_url, filename) 154 | self._is_debug('Downloading the audio challenge..') 155 | AudioSegment.from_mp3(filename).export(wav_output, format='wav') 156 | sample_audio = AudioFile(wav_output) 157 | os.remove(filename) 158 | 159 | recognizer = Recognizer() 160 | with sample_audio as source: 161 | audio = recognizer.record(source) 162 | self._is_debug('Converting audio challenge to text..') 163 | return recognizer.recognize_google(audio), wav_output 164 | 165 | def _click_demo_submit(self): 166 | submit = self.wait.until(poel((By.CSS_SELECTOR, '#recaptcha-demo-submit'))) 167 | self._is_debug('Clicking submit button..') 168 | submit.click() 169 | sleep(uniform(2, 3)) 170 | if 'Hooray' in self.browser.page_source: 171 | self._print_message('\n' + Colors.SUCCESS, f'{Colors.white}Hooray V2 Bypassed! 📍{Colors.reset}\n') 172 | else: 173 | self._print_message('\n' + Colors.WARNING, f'{Colors.white}Bypass Failed! 📍{Colors.reset}\n') 174 | --------------------------------------------------------------------------------