Skip to content

RC-2952-add-report #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 46 additions & 18 deletions examples/cloudflare/cloudflare_challenge_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from twocaptcha import TwoCaptcha
Expand All @@ -17,6 +18,7 @@
url = "https://2captcha.com/demo/cloudflare-turnstile-challenge"
apikey = os.getenv('APIKEY_2CAPTCHA')

solver = TwoCaptcha(apikey)

"""
When a web page first loads, some JavaScript functions and objects (such as window.turnstile) may already be initialized
Expand Down Expand Up @@ -53,9 +55,9 @@

# GETTERS

def get_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
Expand Down Expand Up @@ -89,27 +91,24 @@ def get_captcha_params(script):
print("Parameters received")
return params

def solver_captcha(apikey, params):
def solver_captcha(params):
"""
Solves the Turnstile captcha using the 2Captcha service.

Args:
apikey (str): The 2Captcha API key.
params (dict): The intercepted Turnstile parameters.

Returns:
str: The solved captcha token.
dict: The captcha id and the solved captcha code.
"""
solver = TwoCaptcha(apikey)
try:
result = solver.turnstile(sitekey=params["sitekey"],
url=params["pageurl"],
action=params["action"],
data=params["data"],
pagedata=params["pagedata"],
useragent=params["userAgent"])
print(f"Captcha solved")
return result['code']
print(f"Captcha solved. Token: {result['code']}.")
return result
except Exception as e:
print(f"An error occurred: {e}")
return None
Expand All @@ -125,15 +124,38 @@ def send_token_callback(token):
browser.execute_script(script)
print("The token is sent to the callback function")

def final_message(locator):
def final_message_and_report(locator, id):
"""
Retrieves and prints the final success message.
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.
"""
message = get_element(locator).text
print(message)
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
Expand All @@ -148,15 +170,21 @@ def final_message(locator):
browser.get(url)
print("Started")

# Getting captcha params
params = get_captcha_params(intercept_script)

if params:
token = solver_captcha(apikey, params)
# Sent captcha to the solution in 2captcha API
result = solver_captcha(params)

if token:
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_callback(token)
final_message(success_message_locator)
time.sleep(5)
# 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")
Expand Down
88 changes: 61 additions & 27 deletions examples/cloudflare/cloudflare_turnstile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
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
# 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

Expand All @@ -25,10 +28,14 @@

# GETTERS

def get_element(locator):
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

Expand All @@ -41,27 +48,25 @@ def get_sitekey(locator):
Returns:
str: The sitekey value.
"""
sitekey_element = get_element(locator)
sitekey_element = get_present_element(locator)
sitekey = sitekey_element.get_attribute('data-sitekey')
print(f"Sitekey received: {sitekey}")
return sitekey

def solver_captcha(apikey, sitekey, url):
def solver_captcha(sitekey, url):
"""
Solves the Claudflare Turnstile using the 2Captcha service.

Args:
apikey (str): The 2Captcha API key.
sitekey (str): The sitekey for the captcha.
url (str): The URL where the captcha is located.
Returns:
str: The solved captcha code.
dict: The captcha id and the solved captcha code.
"""
solver = TwoCaptcha(apikey)
try:
result = solver.turnstile(sitekey=sitekey, url=url)
print(f"Captcha solved")
return result['code']
print(f"Captcha solved. Token: {result['code']}.")
return result
except Exception as e:
print(f"An error occurred: {e}")
return None
Expand Down Expand Up @@ -90,40 +95,69 @@ def click_check_button(locator):
Args:
locator (str): The XPath locator of the check button.
"""
get_element(locator).click()
get_clickable_element(locator).click()
print("Pressed the Check button")

def final_message(locator):
def final_message_and_report(locator, id):
"""
Retrieves and prints the final success message.
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.
"""
message = get_element(locator).text
print(message)
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)

token = solver_captcha(apikey, sitekey, url)

if token:

send_token(css_locator_for_input_send_token, token)

click_check_button(submit_button_captcha_locator)

final_message(success_message_locator)

print("Finished")
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 solve captcha")
print("Failed to intercept parameters")


Loading