├── 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 |
--------------------------------------------------------------------------------