Skip to content

Commit 0e06957

Browse files
Merge pull request #7 from 2captcha/RC-2740-cloudflare-challenge-page
RC-2740 cloudflare challenge page
2 parents 96ca1da + 3d472d3 commit 0e06957

File tree

2 files changed

+180
-3
lines changed

2 files changed

+180
-3
lines changed

README.md

+16-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Examples of solving captchas using the Python programming language, and the [2captcha-python] and [Selenium] libraries.
44

5-
This repository contains examples of automation of solving the most popular types of captcha, such as [reCAPTCHA][recaptcha-v2-demo], [Cloudflare Turnstile][cloudflare-turnstile], [normal captcha][normal-captcha-demo], [hCaptcha][hcaptcha-demo] and others. Selenium library is used for browser automation in the examples. The [2Captcha] service is used for solving captchas, therefore, for the correct work of the examples it is necessary to have an account in the [captcha solving service][2Captcha] service with a positive balance, or you can try to test it using [sandbox] mode to solve captchas manually.
5+
This repository contains examples of automation of solving the most popular types of captcha, such as [reCAPTCHA][recaptcha-v2-demo], [Cloudflare Turnstile][cloudflare-turnstile], [Cloudflare Challenge page][cloudflare-challenge], [normal captcha][normal-captcha-demo], [hCaptcha][hcaptcha-demo] and others. Selenium library is used for browser automation in the examples. The [2Captcha] service is used for solving captchas, therefore, for the correct work of the examples it is necessary to have an account in the [captcha solving service][2Captcha] service with a positive balance, or you can try to test it using [sandbox] mode to solve captchas manually.
66
Also, for `proxy` examples to work correctly, you need to have your own `proxy` and set it in the example code. The examples of captcha automation solving use captchas located on the [captchas demo pages](https://2captcha.com/demo).
77

88
We have our own proxies that we can offer you. [Buy residential proxies] to avoid restrictions and blocks. [Quick start].
@@ -28,6 +28,7 @@ Official 2Captcha webpage for [selenium captcha solver](https://2captcha.com/p/s
2828
- [hCaptcha + proxy](#hcaptcha--proxy)
2929
- [Cloudflare example](#cloudflare-example)
3030
- [Cloudflare Turnstile](#cloudflare-turnstile)
31+
- [Cloudflare Challenge page](#cloudflare-challenge-page)
3132
- [Text captcha example](#text-captcha-example)
3233
- [Normal captcha examples](#normal-captcha-examples)
3334
- [Normal captcha (screenshot)](#normal-captcha-screenshot)
@@ -213,16 +214,28 @@ Cloudflare is one of the most popular captcha types. Cloudflare has two types. F
213214

214215
- [Cloudflare challenge][cloudflare-challenge] - In this case, a redirect to the challenge page will occur to pass the captcha, as implemented here https://2captcha.com/demo/cloudflare-turnstile-challenge.
215216

216-
The approach to bypassing these two types is different, so you need to determine which type of Cloudflare you are facing. Read more about bypassing Cloudflare Turnstile type below.
217+
The approach to bypassing these two types is different, so you need to determine which type of Cloudflare you are facing. Read more about bypassing Cloudflare captcha types below.
217218

218219
#### Cloudflare Turnstile
219220

220221
Token-based Cloudflare Turnstile solution.
221222

222-
This example demonstrates how to bypass the Cloudflare Turnstile CAPTCHA located on the page https://2captcha.com/demo/cloudflare-turnstile. The Selenium library is used to automate browser actions and retrieve CAPTCHA parameters. To solve this type of Cloudflare CAPTCHA, it is necessary to send parameters such as pageurl and sitekey to the [2Captcha API](https://2captcha.com/2captcha-api#turnstile). After receiving the solution result (token), the script automatically uses the received answer on the page.
223+
This example demonstrates how to bypass the Cloudflare Turnstile CAPTCHA located on the page https://2captcha.com/demo/cloudflare-turnstile. The Selenium library is used to automate browser actions and retrieve CAPTCHA parameters. To solve this type of Cloudflare CAPTCHA, it is necessary to send parameters such as `pageurl` and `sitekey` to the [2Captcha API](https://2captcha.com/2captcha-api#turnstile). After receiving the solution result (token), the script automatically uses the received answer on the page.
223224

224225
**Source code:** [`./examples/cloudflare_turnstile/cloudflare_turnstile.py`](./examples/cloudflare_turnstile/cloudflare_turnstile.py)
225226

227+
228+
#### Cloudflare Challenge page
229+
230+
Token-based Cloudflare Challenge page solution.
231+
232+
This example demonstrates how to bypass the Cloudflare Challenge located on the page https://2captcha.com/demo/cloudflare-turnstile-challenge. The Selenium library is used to automate browser actions and retrieve CAPTCHA parameters. To solve this type of Cloudflare CAPTCHA, it is necessary to send parameters such as `pageurl`,`sitekey`, `action`, `data`, `pagedata`, `useragent` to the [2Captcha API](https://2captcha.com/2captcha-api#turnstile). After receiving the solution result (token), the script automatically uses the received answer on the page.
233+
234+
> [!NOTE]
235+
> When a web page first loads, some JavaScript functions and objects (such as `window.turnstile`) may already be initialized and executed. If the interception script is launched too late, this may lead to the fact that the necessary parameters will already be lost, or the script simply will not have time to intercept the right moment. Refreshing the page ensures that everything starts from scratch and you trigger the interception at the right time.
236+
237+
**Source code:** [`./examples/cloudflare_challenge_page/cloudflare_challenge_page.py`](./examples/cloudflare_challenge_page/cloudflare_challenge_page.py)
238+
226239
### Text captcha example
227240

228241
Text captcha solutions.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import os
2+
import time
3+
import json
4+
import re
5+
from selenium import webdriver
6+
from selenium.webdriver.support.wait import WebDriverWait
7+
from selenium.webdriver.common.by import By
8+
from selenium.webdriver.support import expected_conditions as EC
9+
from selenium.webdriver.chrome.service import Service
10+
from selenium.webdriver.chrome.options import Options
11+
from twocaptcha import TwoCaptcha
12+
13+
14+
15+
# CONFIGURATION
16+
17+
url = "https://2captcha.com/demo/cloudflare-turnstile-challenge"
18+
apikey = os.getenv('APIKEY_2CAPTCHA')
19+
20+
21+
"""
22+
When a web page first loads, some JavaScript functions and objects (such as window.turnstile) may already be initialized
23+
and executed. If the interception script is launched too late, this may lead to the fact that the necessary parameters
24+
will already be lost, or the script simply will not have time to intercept the right moment. Refreshing the page ensures
25+
that everything starts from scratch and you trigger the interception at the right time.
26+
"""
27+
intercept_script = """
28+
console.clear = () => console.log('Console was cleared')
29+
const i = setInterval(()=>{
30+
if (window.turnstile)
31+
console.log('success!!')
32+
{clearInterval(i)
33+
window.turnstile.render = (a,b) => {
34+
let params = {
35+
sitekey: b.sitekey,
36+
pageurl: window.location.href,
37+
data: b.cData,
38+
pagedata: b.chlPageData,
39+
action: b.action,
40+
userAgent: navigator.userAgent,
41+
}
42+
console.log('intercepted-params:' + JSON.stringify(params))
43+
window.cfCallback = b.callback
44+
return }
45+
}
46+
},50)
47+
"""
48+
49+
# LOCATORS
50+
51+
success_message_locator = "//p[contains(@class,'successMessage')]"
52+
53+
54+
# GETTERS
55+
56+
def get_element(locator):
57+
"""Waits for an element to be clickable and returns it"""
58+
return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator)))
59+
60+
61+
# ACTIONS
62+
63+
def get_captcha_params(script):
64+
"""
65+
Refreshes the page, injects a JavaScript script to intercept Turnstile parameters, and retrieves them.
66+
67+
Args:
68+
script (str): The JavaScript code to be injected.
69+
70+
Returns:
71+
dict: The intercepted Turnstile parameters as a dictionary.
72+
"""
73+
browser.refresh() # Refresh the page to ensure the script is applied correctly
74+
75+
browser.execute_script(script) # Inject the interception script
76+
77+
time.sleep(5) # Allow some time for the script to execute
78+
79+
logs = browser.get_log("browser") # Retrieve the browser logs
80+
params = None
81+
for log in logs:
82+
if "intercepted-params:" in log['message']:
83+
log_entry = log['message'].encode('utf-8').decode('unicode_escape')
84+
match = re.search(r'intercepted-params:({.*?})', log_entry)
85+
if match:
86+
json_string = match.group(1)
87+
params = json.loads(json_string)
88+
break
89+
print("Parameters received")
90+
return params
91+
92+
def solver_captcha(apikey, params):
93+
"""
94+
Solves the Turnstile captcha using the 2Captcha service.
95+
96+
Args:
97+
apikey (str): The 2Captcha API key.
98+
params (dict): The intercepted Turnstile parameters.
99+
100+
Returns:
101+
str: The solved captcha token.
102+
"""
103+
solver = TwoCaptcha(apikey)
104+
try:
105+
result = solver.turnstile(sitekey=params["sitekey"],
106+
url=params["pageurl"],
107+
action=params["action"],
108+
data=params["data"],
109+
pagedata=params["pagedata"],
110+
useragent=params["userAgent"])
111+
print(f"Captcha solved")
112+
return result['code']
113+
except Exception as e:
114+
print(f"An error occurred: {e}")
115+
return None
116+
117+
def send_token_callback(token):
118+
"""
119+
Executes the callback function with the given token.
120+
121+
Args:
122+
token (str): The solved captcha token.
123+
"""
124+
script = f"cfCallback('{token}')"
125+
browser.execute_script(script)
126+
print("The token is sent to the callback function")
127+
128+
def final_message(locator):
129+
"""
130+
Retrieves and prints the final success message.
131+
132+
Args:
133+
locator (str): The XPath locator of the success message.
134+
"""
135+
message = get_element(locator).text
136+
print(message)
137+
138+
139+
# MAIN LOGIC
140+
141+
chrome_options = Options()
142+
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
143+
"Chrome/126.0.0.0 Safari/537.36")
144+
# Set logging preferences to capture only console logs
145+
chrome_options.set_capability("goog:loggingPrefs", {"browser": "INFO"})
146+
147+
with webdriver.Chrome(service=Service(), options=chrome_options) as browser:
148+
browser.get(url)
149+
print("Started")
150+
151+
params = get_captcha_params(intercept_script)
152+
153+
if params:
154+
token = solver_captcha(apikey, params)
155+
156+
if token:
157+
send_token_callback(token)
158+
final_message(success_message_locator)
159+
time.sleep(5)
160+
print("Finished")
161+
else:
162+
print("Failed to solve captcha")
163+
else:
164+
print("Failed to intercept parameters")

0 commit comments

Comments
 (0)