Skip to content

Commit d30ce64

Browse files
committed
fix: improve Cloudflare challenge detection and handling logic
1 parent f7a2568 commit d30ce64

1 file changed

Lines changed: 42 additions & 17 deletions

File tree

cf_bypasser/core/bypasser.py

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,14 @@ async def is_bypassed(self, page) -> bool:
127127
"""Check if Cloudflare challenge has been bypassed."""
128128
try:
129129
title = await page.title()
130+
if "just a moment" in title.lower():
131+
return False
130132
html_content = await page.content()
131-
return "just a moment" not in title.lower() and "please complete the captcha" not in html_content.lower()
133+
if "please complete the captcha" in html_content.lower():
134+
return False
135+
return True
132136
except Exception as e:
133-
self.log_message(f"Error checking page title: {e}")
137+
self.log_message(f"Error checking bypass status: {e}")
134138
return False
135139

136140
async def determine_challenge_type(self, page) -> CaptchaType:
@@ -153,45 +157,66 @@ async def solve_cloudflare_challenge(self, url: str, page) -> bool:
153157
try:
154158
# Navigate to the target URL
155159
self.log_message(f"Navigating to {url}")
156-
await page.goto(url, wait_until="networkidle", timeout=10000)
160+
try:
161+
await page.goto(url, wait_until="domcontentloaded", timeout=30000)
162+
except Exception as nav_err:
163+
self.log_message(f"Navigation warning: {nav_err}")
164+
# Wait for challenge scripts to load and execute
157165
await asyncio.sleep(5)
158-
html_content = await page.content()
159-
160-
if "cloudflare" not in html_content:
166+
try:
167+
html_content = await page.content()
168+
except Exception:
169+
html_content = ""
170+
171+
if "cloudflare" not in html_content.lower():
161172
self.log_message("No Cloudflare protection detected on the page -- either not protected or already bypassed")
162173
return True
163-
174+
164175
# Check if we need to solve a challenge
165176
if await self.is_bypassed(page):
166177
self.log_message("No Cloudflare challenge detected or already bypassed")
167178
return True
168179

169-
self.log_message("Cloudflare challenge detected. Attempting to solve...")
180+
self.log_message("Cloudflare challenge detected. Waiting for auto-resolve...")
181+
182+
# Most Cloudflare interstitial challenges now auto-resolve without
183+
# user interaction. Poll for the challenge to clear before trying
184+
# the click solver.
185+
for i in range(self.max_retries):
186+
await asyncio.sleep(5)
187+
try:
188+
if await self.is_bypassed(page):
189+
self.log_message("Cloudflare challenge auto-resolved")
190+
await asyncio.sleep(1)
191+
return True
192+
except Exception:
193+
# Page may be navigating — that's a good sign
194+
pass
195+
196+
# If auto-resolve failed, try the click solver as a fallback
197+
# (for turnstile or interactive challenges)
198+
self.log_message("Auto-resolve timed out. Attempting click solver...")
170199
challenge_type = await self.determine_challenge_type(page)
171200
if not challenge_type:
172201
self.log_message("Could not determine challenge type")
173202
return False
174-
203+
175204
expected_selector = "#root"
176205
captcha_container = page
177-
is_solved = False
178-
async with ClickSolver(framework=FrameworkType.CAMOUFOX, page=page, max_attempts=2, attempt_delay=1) as solver:
179-
206+
is_solved = False
207+
async with ClickSolver(framework=FrameworkType.CAMOUFOX, page=page, max_attempts=3, attempt_delay=2) as solver:
180208
await solver.solve_captcha(
181209
captcha_container=captcha_container,
182210
captcha_type=challenge_type,
183211
expected_content_selector=expected_selector,)
184-
185212
is_solved = "just a moment" not in await page.title()
186-
187213

188214
if is_solved:
189-
self.log_message("✅ Cloudflare challenge solved successfully!")
190-
# Wait a bit more to ensure cookies are set
215+
self.log_message("Cloudflare challenge solved successfully!")
191216
await asyncio.sleep(1)
192217
return True
193218
else:
194-
self.log_message("Failed to solve Cloudflare challenge")
219+
self.log_message("Failed to solve Cloudflare challenge")
195220
return False
196221

197222
except Exception as e:

0 commit comments

Comments
 (0)