-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcloudflare_turnstile.py
163 lines (130 loc) · 5.27 KB
/
cloudflare_turnstile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import os
from twocaptcha import TwoCaptcha
# Description:
# In this example, you will learn how to bypass the Cloudflare Turnstile CAPTCHA located on the page https://2captcha.com/demo/cloudflare-turnstile.
# This demonstration will guide you through the steps of interacting with and overcoming the CAPTCHA using specific techniques
# The value of the `sitekey` parameter is extracted from the page code automaticly.
# CONFIGURATION
url = "https://2captcha.com/demo/cloudflare-turnstile"
apikey = os.getenv('APIKEY_2CAPTCHA')
solver = TwoCaptcha(apikey)
# LOCATORS
sitekey_locator = "//div[@id='cf-turnstile']"
css_locator_for_input_send_token = 'input[name="cf-turnstile-response"]'
submit_button_captcha_locator = "//button[@type='submit']"
success_message_locator = "//p[contains(@class,'successMessage')]"
# GETTERS
def get_clickable_element(locator):
"""Waits for an element to be clickable and returns it"""
return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator)))
def get_present_element(locator):
"""Waits for an element to be present and returns it"""
return WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.XPATH, locator)))
# ACTIONS
def get_sitekey(locator):
"""
Extracts the sitekey from the specified element.
Args:
locator (str): The XPath locator of the element containing the sitekey.
Returns:
str: The sitekey value.
"""
sitekey_element = get_present_element(locator)
sitekey = sitekey_element.get_attribute('data-sitekey')
print(f"Sitekey received: {sitekey}")
return sitekey
def solver_captcha(sitekey, url):
"""
Solves the Claudflare Turnstile using the 2Captcha service.
Args:
sitekey (str): The sitekey for the captcha.
url (str): The URL where the captcha is located.
Returns:
dict: The captcha id and the solved captcha code.
"""
try:
result = solver.turnstile(sitekey=sitekey, url=url)
print(f"Captcha solved. Token: {result['code']}.")
return result
except Exception as e:
print(f"An error occurred: {e}")
return None
def send_token(css_locator, captcha_token):
"""
Sends the captcha token to the Claudflare Turnstile response field.
Args:
css_locator (str): The CSS locator for the input field.
captcha_token (str): The solved captcha token.
"""
script = f"""
var element = document.querySelector('{css_locator}');
if (element) {{
element.value = "{captcha_token}";
}}
"""
browser.execute_script(script)
print("Token sent")
def click_check_button(locator):
"""
Clicks the captcha check button.
Args:
locator (str): The XPath locator of the check button.
"""
get_clickable_element(locator).click()
print("Pressed the Check button")
def final_message_and_report(locator, id):
"""
Retrieves and prints the final success message and sends a report to 2Captcha.
Submitting answer reports is not necessary to solve the captcha. But it can help you reduce the cost of the solution
and improve accuracy. We have described why it is important to submit reports in our blog:
https://2captcha.com/ru/blog/reportgood-reportbad
We recommend reporting both incorrect and correct answers.
Args:
locator (str): The XPath locator of the success message.
id (str): The captcha id for reporting.
"""
try:
# Check for success message
message = get_present_element(locator).text
print(message)
is_success = True
except TimeoutException:
# If the element is not found within the timeout
print("Timed out waiting for success message element")
is_success = False
except Exception as e:
# If another error occurs
print(f"Error retrieving final message: {e}")
is_success = False
# Send the report anyway
solver.report(id, is_success)
print(f"Report sent for id: {id}, success: {is_success}")
# MAIN LOGIC
with webdriver.Chrome() as browser:
browser.get(url)
print('Started')
# Getting a site key
sitekey = get_sitekey(sitekey_locator)
if sitekey:
# Sent captcha to the solution in 2captcha API
result = solver_captcha(sitekey, url)
if result:
# From the response from the service we get the captcha id and token
id, token = result['captchaId'], result['code']
# Applying the token on the page
send_token(css_locator_for_input_send_token, token)
# Checking whether the token has been accepted
click_check_button(submit_button_captcha_locator)
# We check if there is a message about the successful solution of the captcha and send a report on the result
# using the captcha id
final_message_and_report(success_message_locator, id)
print("Finished")
else:
print("Failed to solve captcha")
else:
print("Failed to intercept parameters")