HerzaJ commited on
Commit
fed717a
·
verified ·
1 Parent(s): d042d90

Update solver.py

Browse files
Files changed (1) hide show
  1. solver.py +307 -163
solver.py CHANGED
@@ -1,193 +1,329 @@
1
  import time
2
  import json
3
  import logging
4
- from selenium import webdriver
5
- from selenium.webdriver.common.by import By
6
- from selenium.webdriver.support.ui import WebDriverWait
7
- from selenium.webdriver.support import expected_conditions as EC
8
- from selenium.webdriver.chrome.options import Options
9
- from selenium.webdriver.chrome.service import Service
10
 
11
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
12
  logger = logging.getLogger(__name__)
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  class HCaptchaSolver:
15
  def __init__(self):
16
- self.driver = None
17
- self.wait = None
18
- self.setup_driver()
19
-
20
- def setup_driver(self):
21
- chrome_options = Options()
22
- chrome_options.binary_location = '/usr/bin/chromium'
23
- chrome_options.add_argument('--no-sandbox')
24
- chrome_options.add_argument('--disable-dev-shm-usage')
25
- chrome_options.add_argument('--disable-gpu')
26
- chrome_options.add_argument('--disable-software-rasterizer')
27
- chrome_options.add_argument('--disable-dev-tools')
28
- chrome_options.add_argument('--no-zygote')
29
- chrome_options.add_argument('--single-process')
30
- chrome_options.add_argument('--window-size=1920,1080')
31
- chrome_options.add_argument('--headless=new')
32
- chrome_options.add_argument('--disable-blink-features=AutomationControlled')
33
- chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
34
- chrome_options.add_experimental_option('useAutomationExtension', False)
35
- chrome_options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')
36
-
37
- service = Service('/usr/bin/chromedriver')
38
- self.driver = webdriver.Chrome(service=service, options=chrome_options)
39
- self.wait = WebDriverWait(self.driver, 30)
40
-
41
- self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
42
- 'source': '''
43
- Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
44
- Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5]});
45
- Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
46
- window.chrome = {runtime: {}};
47
- '''
48
- })
49
-
50
- logger.info("Chrome driver setup complete")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  def open_page(self):
53
  logger.info("Opening bylo.ai...")
54
- self.driver.get("https://bylo.ai/features/sora-2")
55
- time.sleep(3)
56
 
57
  def click_login_button(self):
58
- logger.info("Clicking login button...")
59
- login_btn = self.wait.until(
60
- EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.flex.items-center.gap-3'))
61
- )
62
- login_btn.click()
63
- time.sleep(2)
 
 
 
 
64
 
65
  def click_signup(self):
66
- logger.info("Clicking Sign Up...")
67
- signup = self.wait.until(
68
- EC.element_to_be_clickable((By.XPATH, "//span[text()='Sign Up']"))
69
- )
70
- signup.click()
71
- time.sleep(2)
 
 
 
 
72
 
73
  def fill_email(self, email):
74
  logger.info(f"Filling email: {email}")
75
- email_input = self.wait.until(
76
- EC.presence_of_element_located((By.CSS_SELECTOR, 'input[name="email"]'))
77
- )
78
- email_input.clear()
79
- email_input.send_keys(email)
80
- time.sleep(1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  def click_get_code(self):
83
  logger.info("Clicking Get Code...")
84
- get_code = self.wait.until(
85
- EC.element_to_be_clickable((By.XPATH, "//button[text()='Get Code']"))
86
- )
87
- get_code.click()
88
- time.sleep(3)
89
-
90
- def solve_hcaptcha_auto(self):
91
- logger.info("Starting hCaptcha auto solve...")
92
-
93
- time.sleep(3)
94
 
95
- iframes = self.driver.find_elements(By.TAG_NAME, 'iframe')
96
- logger.info(f"Found {len(iframes)} iframes")
 
 
97
 
98
- for idx, iframe in enumerate(iframes):
99
- try:
100
- iframe_src = iframe.get_attribute('src')
101
-
102
- if iframe_src and 'hcaptcha.com/captcha' in iframe_src:
103
- logger.info(f"Found hCaptcha iframe at index {idx}")
 
 
 
 
 
 
 
104
 
105
- self.driver.switch_to.frame(iframe)
 
 
 
 
 
 
 
 
 
 
 
106
  time.sleep(2)
107
 
108
- try:
109
- checkbox = self.wait.until(
110
- EC.element_to_be_clickable((By.CSS_SELECTOR, '#checkbox'))
111
- )
112
- logger.info("Clicking checkbox...")
113
- checkbox.click()
114
- time.sleep(3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- self.driver.switch_to.default_content()
117
- time.sleep(3)
118
 
119
- token = self.get_hcaptcha_token()
120
- if token:
121
- return token
122
-
123
- except Exception as e:
124
- logger.warning(f"Checkbox not found in this iframe: {e}")
125
- self.driver.switch_to.default_content()
126
 
127
- except Exception as e:
128
- logger.warning(f"Error processing iframe {idx}: {e}")
129
- self.driver.switch_to.default_content()
130
-
131
- logger.info("Trying JavaScript bypass...")
132
-
133
- bypass_script = """
134
- var response = document.querySelector('[name="h-captcha-response"]');
135
- if (response && response.value) {
136
- return response.value;
137
- }
 
 
 
 
 
138
 
139
- if (window.hcaptcha) {
140
- try {
141
- var widgetID = window.hcaptcha.render(document.querySelector('.h-captcha'));
142
- window.hcaptcha.execute(widgetID);
143
- } catch(e) {}
144
- }
145
 
146
- return null;
147
- """
148
-
149
- for attempt in range(15):
150
- result = self.driver.execute_script(bypass_script)
151
- if result:
152
- logger.info("Token obtained from JavaScript bypass!")
153
- return result
154
 
155
- time.sleep(2)
156
- logger.info(f"Bypass attempt {attempt + 1}/15")
157
-
158
- logger.info("Waiting for token to appear...")
159
- for i in range(40):
160
- token = self.get_hcaptcha_token()
161
- if token:
162
- return token
163
- time.sleep(1)
164
 
165
- return None
 
 
 
 
 
166
 
167
  def get_hcaptcha_token(self):
168
  try:
169
- token = self.driver.execute_script("""
170
- var elements = [
171
- document.querySelector('textarea[name="h-captcha-response"]'),
172
- document.querySelector('[data-hcaptcha-response]'),
173
- document.querySelector('input[name="h-captcha-response"]')
174
- ];
175
-
176
- for (var el of elements) {
177
- if (el && el.value) {
178
- return el.value;
179
- }
180
- if (el && el.getAttribute('data-hcaptcha-response')) {
181
- return el.getAttribute('data-hcaptcha-response');
 
 
182
  }
 
 
183
  }
184
-
185
- return null;
186
  """)
187
 
188
  if token and len(token) > 10:
189
- logger.info(f"TOKEN FOUND: {token[:50]}...")
190
- logger.info(f"Token length: {len(token)}")
 
 
 
191
  return token
192
 
193
  except Exception as e:
@@ -197,13 +333,22 @@ class HCaptchaSolver:
197
 
198
  def run(self, email="herzfnf@gmail.com"):
199
  try:
 
200
  self.open_page()
201
- self.click_login_button()
202
- self.click_signup()
203
- self.fill_email(email)
204
- self.click_get_code()
205
 
206
- token = self.solve_hcaptcha_auto()
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
  if token:
209
  logger.info("SUCCESS! Token retrieved")
@@ -225,19 +370,18 @@ class HCaptchaSolver:
225
  "success": False,
226
  "error": str(e)
227
  }
 
 
228
 
229
  def cleanup(self):
230
- if self.driver:
231
- self.driver.quit()
232
  logger.info("Browser closed")
233
 
234
  if __name__ == "__main__":
235
  solver = HCaptchaSolver()
236
- try:
237
- result = solver.run("herzfnf@gmail.com")
238
- print("\n" + "="*60)
239
- print("RESULT:")
240
- print(json.dumps(result, indent=2))
241
- print("="*60)
242
- finally:
243
- solver.cleanup()
 
1
  import time
2
  import json
3
  import logging
4
+ import random
5
+ import math
6
+ from camoufox.sync_api import Camoufox
7
+ from playwright.sync_api import sync_playwright
 
 
8
 
9
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
10
  logger = logging.getLogger(__name__)
11
 
12
+ class HumanMouseMovement:
13
+ @staticmethod
14
+ def bezier_curve(start, end, steps=50):
15
+ points = []
16
+ control1 = (
17
+ start[0] + random.randint(-100, 100),
18
+ start[1] + random.randint(-100, 100)
19
+ )
20
+ control2 = (
21
+ end[0] + random.randint(-100, 100),
22
+ end[1] + random.randint(-100, 100)
23
+ )
24
+
25
+ for i in range(steps + 1):
26
+ t = i / steps
27
+ x = (1-t)**3 * start[0] + 3*(1-t)**2*t * control1[0] + 3*(1-t)*t**2 * control2[0] + t**3 * end[0]
28
+ y = (1-t)**3 * start[1] + 3*(1-t)**2*t * control1[1] + 3*(1-t)*t**2 * control2[1] + t**3 * end[1]
29
+
30
+ shake_x = random.uniform(-2, 2)
31
+ shake_y = random.uniform(-2, 2)
32
+
33
+ points.append((x + shake_x, y + shake_y))
34
+
35
+ return points
36
+
37
+ @staticmethod
38
+ def add_micro_movements(x, y):
39
+ micro_x = x + random.uniform(-1, 1)
40
+ micro_y = y + random.uniform(-1, 1)
41
+ return micro_x, micro_y
42
+
43
  class HCaptchaSolver:
44
  def __init__(self):
45
+ self.browser = None
46
+ self.page = None
47
+ self.context = None
48
+
49
+ def setup_browser(self):
50
+ logger.info("Setting up Camoufox browser...")
51
+
52
+ self.browser = Camoufox(
53
+ headless=True,
54
+ humanize=True,
55
+ geoip=True,
56
+ exclude_addons=['uBlock0@raymondhill.net']
57
+ )
58
+
59
+ self.context = self.browser.new_context(
60
+ viewport={'width': 1920, 'height': 1080},
61
+ user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
62
+ locale='en-US',
63
+ timezone_id='America/New_York'
64
+ )
65
+
66
+ self.page = self.context.new_page()
67
+
68
+ self.page.add_init_script("""
69
+ Object.defineProperty(navigator, 'webdriver', {
70
+ get: () => undefined
71
+ });
72
+
73
+ window.chrome = {
74
+ runtime: {},
75
+ };
76
+
77
+ Object.defineProperty(navigator, 'plugins', {
78
+ get: () => [1, 2, 3, 4, 5],
79
+ });
80
+ """)
81
+
82
+ logger.info("Camoufox browser setup complete")
83
+
84
+ def human_mouse_move(self, target_x, target_y):
85
+ current_pos = self.page.evaluate("""
86
+ () => ({x: window.mouseX || 0, y: window.mouseY || 0})
87
+ """)
88
+
89
+ start = (current_pos['x'], current_pos['y'])
90
+ end = (target_x, target_y)
91
+
92
+ points = HumanMouseMovement.bezier_curve(start, end, steps=random.randint(30, 60))
93
+
94
+ for x, y in points:
95
+ micro_x, micro_y = HumanMouseMovement.add_micro_movements(x, y)
96
+ self.page.mouse.move(micro_x, micro_y)
97
+ time.sleep(random.uniform(0.001, 0.005))
98
+
99
+ self.page.evaluate(f"window.mouseX = {target_x}; window.mouseY = {target_y};")
100
+
101
+ def human_click(self, selector=None, x=None, y=None):
102
+ if selector:
103
+ element = self.page.locator(selector)
104
+ box = element.bounding_box()
105
+ if box:
106
+ click_x = box['x'] + box['width'] / 2 + random.uniform(-5, 5)
107
+ click_y = box['y'] + box['height'] / 2 + random.uniform(-5, 5)
108
+ else:
109
+ return False
110
+ else:
111
+ click_x = x
112
+ click_y = y
113
+
114
+ self.human_mouse_move(click_x, click_y)
115
+
116
+ time.sleep(random.uniform(0.05, 0.15))
117
+
118
+ for _ in range(random.randint(1, 3)):
119
+ offset_x = random.uniform(-1, 1)
120
+ offset_y = random.uniform(-1, 1)
121
+ self.page.mouse.move(click_x + offset_x, click_y + offset_y)
122
+ time.sleep(random.uniform(0.01, 0.03))
123
+
124
+ self.page.mouse.down()
125
+ time.sleep(random.uniform(0.05, 0.12))
126
+ self.page.mouse.up()
127
+
128
+ time.sleep(random.uniform(0.1, 0.3))
129
+
130
+ return True
131
 
132
  def open_page(self):
133
  logger.info("Opening bylo.ai...")
134
+ self.page.goto("https://bylo.ai/features/sora-2", wait_until="networkidle")
135
+ time.sleep(random.uniform(2, 4))
136
 
137
  def click_login_button(self):
138
+ logger.info("Looking for login button...")
139
+ try:
140
+ self.page.wait_for_selector('button.flex.items-center.gap-3', timeout=10000)
141
+ self.human_click('button.flex.items-center.gap-3')
142
+ logger.info("Login button clicked")
143
+ time.sleep(random.uniform(1.5, 2.5))
144
+ return True
145
+ except Exception as e:
146
+ logger.error(f"Error clicking login: {e}")
147
+ return False
148
 
149
  def click_signup(self):
150
+ logger.info("Looking for Sign Up...")
151
+ try:
152
+ self.page.wait_for_selector("//span[text()='Sign Up']", timeout=10000)
153
+ self.human_click("//span[text()='Sign Up']")
154
+ logger.info("Sign Up clicked")
155
+ time.sleep(random.uniform(1.5, 2.5))
156
+ return True
157
+ except Exception as e:
158
+ logger.error(f"Error clicking signup: {e}")
159
+ return False
160
 
161
  def fill_email(self, email):
162
  logger.info(f"Filling email: {email}")
163
+ try:
164
+ self.page.wait_for_selector('input[name="email"]', timeout=10000)
165
+
166
+ email_input = self.page.locator('input[name="email"]')
167
+ box = email_input.bounding_box()
168
+
169
+ if box:
170
+ click_x = box['x'] + box['width'] / 2
171
+ click_y = box['y'] + box['height'] / 2
172
+ self.human_mouse_move(click_x, click_y)
173
+ self.page.mouse.click(click_x, click_y)
174
+
175
+ time.sleep(random.uniform(0.3, 0.6))
176
+
177
+ for char in email:
178
+ self.page.keyboard.type(char)
179
+ time.sleep(random.uniform(0.08, 0.25))
180
+
181
+ logger.info("Email filled")
182
+ time.sleep(random.uniform(0.5, 1))
183
+ return True
184
+ except Exception as e:
185
+ logger.error(f"Error filling email: {e}")
186
+ return False
187
 
188
  def click_get_code(self):
189
  logger.info("Clicking Get Code...")
190
+ try:
191
+ self.page.wait_for_selector("//button[text()='Get Code']", timeout=10000)
192
+ self.human_click("//button[text()='Get Code']")
193
+ logger.info("Get Code clicked")
194
+ time.sleep(random.uniform(2, 3))
195
+ return True
196
+ except Exception as e:
197
+ logger.error(f"Error clicking get code: {e}")
198
+ return False
 
199
 
200
+ def solve_hcaptcha(self):
201
+ logger.info("="*60)
202
+ logger.info("Starting hCaptcha solving process...")
203
+ logger.info("="*60)
204
 
205
+ try:
206
+ time.sleep(3)
207
+
208
+ logger.info("Looking for hCaptcha iframe...")
209
+
210
+ frames = self.page.frames
211
+ logger.info(f"Found {len(frames)} frames")
212
+
213
+ hcaptcha_frame = None
214
+ for frame in frames:
215
+ try:
216
+ frame_url = frame.url
217
+ logger.info(f"Frame URL: {frame_url[:100]}")
218
 
219
+ if 'hcaptcha.com/captcha' in frame_url:
220
+ logger.info("Found hCaptcha checkbox frame!")
221
+ hcaptcha_frame = frame
222
+ break
223
+ except:
224
+ continue
225
+
226
+ if not hcaptcha_frame:
227
+ logger.warning("hCaptcha frame not found, trying alternative methods...")
228
+
229
+ for i in range(5):
230
+ logger.info(f"Waiting for hCaptcha to load... attempt {i+1}/5")
231
  time.sleep(2)
232
 
233
+ frames = self.page.frames
234
+ for frame in frames:
235
+ try:
236
+ if 'hcaptcha.com/captcha' in frame.url:
237
+ hcaptcha_frame = frame
238
+ break
239
+ except:
240
+ continue
241
+
242
+ if hcaptcha_frame:
243
+ break
244
+
245
+ if hcaptcha_frame:
246
+ logger.info("Attempting to click hCaptcha checkbox...")
247
+
248
+ try:
249
+ checkbox = hcaptcha_frame.locator('#checkbox')
250
+
251
+ checkbox.wait_for(timeout=5000)
252
+
253
+ box = checkbox.bounding_box()
254
+ if box:
255
+ click_x = box['x'] + box['width'] / 2 + random.uniform(-3, 3)
256
+ click_y = box['y'] + box['height'] / 2 + random.uniform(-3, 3)
257
 
258
+ self.human_mouse_move(click_x, click_y)
 
259
 
260
+ time.sleep(random.uniform(0.5, 1))
 
 
 
 
 
 
261
 
262
+ for _ in range(random.randint(2, 4)):
263
+ micro_x = click_x + random.uniform(-2, 2)
264
+ micro_y = click_y + random.uniform(-2, 2)
265
+ self.page.mouse.move(micro_x, micro_y)
266
+ time.sleep(random.uniform(0.02, 0.05))
267
+
268
+ self.page.mouse.down()
269
+ time.sleep(random.uniform(0.08, 0.15))
270
+ self.page.mouse.up()
271
+
272
+ logger.info("Checkbox clicked!")
273
+
274
+ time.sleep(random.uniform(2, 4))
275
+
276
+ except Exception as e:
277
+ logger.error(f"Error clicking checkbox: {e}")
278
 
279
+ logger.info("Waiting for hCaptcha token...")
 
 
 
 
 
280
 
281
+ for attempt in range(40):
282
+ token = self.get_hcaptcha_token()
283
+ if token:
284
+ return token
 
 
 
 
285
 
286
+ time.sleep(1)
287
+
288
+ if attempt % 5 == 0:
289
+ logger.info(f"Still waiting for token... {attempt}s")
 
 
 
 
 
290
 
291
+ logger.warning("Token not found after waiting")
292
+ return None
293
+
294
+ except Exception as e:
295
+ logger.error(f"Error solving hCaptcha: {e}")
296
+ return None
297
 
298
  def get_hcaptcha_token(self):
299
  try:
300
+ token = self.page.evaluate("""
301
+ () => {
302
+ const elements = [
303
+ document.querySelector('textarea[name="h-captcha-response"]'),
304
+ document.querySelector('[data-hcaptcha-response]'),
305
+ document.querySelector('input[name="h-captcha-response"]')
306
+ ];
307
+
308
+ for (let el of elements) {
309
+ if (el && el.value && el.value.length > 10) {
310
+ return el.value;
311
+ }
312
+ if (el && el.getAttribute('data-hcaptcha-response')) {
313
+ return el.getAttribute('data-hcaptcha-response');
314
+ }
315
  }
316
+
317
+ return null;
318
  }
 
 
319
  """)
320
 
321
  if token and len(token) > 10:
322
+ logger.info("="*60)
323
+ logger.info("TOKEN FOUND!")
324
+ logger.info(f"Token: {token[:50]}...")
325
+ logger.info(f"Length: {len(token)}")
326
+ logger.info("="*60)
327
  return token
328
 
329
  except Exception as e:
 
333
 
334
  def run(self, email="herzfnf@gmail.com"):
335
  try:
336
+ self.setup_browser()
337
  self.open_page()
 
 
 
 
338
 
339
+ if not self.click_login_button():
340
+ raise Exception("Failed to click login button")
341
+
342
+ if not self.click_signup():
343
+ raise Exception("Failed to click signup")
344
+
345
+ if not self.fill_email(email):
346
+ raise Exception("Failed to fill email")
347
+
348
+ if not self.click_get_code():
349
+ raise Exception("Failed to click get code")
350
+
351
+ token = self.solve_hcaptcha()
352
 
353
  if token:
354
  logger.info("SUCCESS! Token retrieved")
 
370
  "success": False,
371
  "error": str(e)
372
  }
373
+ finally:
374
+ self.cleanup()
375
 
376
  def cleanup(self):
377
+ if self.browser:
378
+ self.browser.close()
379
  logger.info("Browser closed")
380
 
381
  if __name__ == "__main__":
382
  solver = HCaptchaSolver()
383
+ result = solver.run("herzfnf@gmail.com")
384
+ print("\n" + "="*60)
385
+ print("FINAL RESULT:")
386
+ print(json.dumps(result, indent=2))
387
+ print("="*60)