Skip to content

Commit 8d98909

Browse files
committed
Added examples:
- coordinates.py to the coordinates folder - normal_captcha_screenshot_params.py to the normal_captcha folder - recaptcha_v3.py, recaptcha_v3_extended_js_script.py, recaptcha_v3_proxy.py to the reCaptcha folder
1 parent f6c2a1c commit 8d98909

File tree

5 files changed

+864
-0
lines changed

5 files changed

+864
-0
lines changed

examples/coordinates/coordinates.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.support.wait import WebDriverWait
4+
from selenium.webdriver.support import expected_conditions as EC
5+
from selenium.webdriver.common.action_chains import ActionChains
6+
import os
7+
from twocaptcha import TwoCaptcha
8+
9+
10+
# CONFIGURATION
11+
12+
url = "https://2captcha.com/demo/clickcaptcha"
13+
apikey = os.getenv('APIKEY_2CAPTCHA')
14+
15+
16+
# LOCATORS
17+
18+
img_locator_captcha_for_get = "._widgetForm_1f3oo_26 img"
19+
img_locator_captcha_for_click = "//div[@class='_widget_s7q0j_5']//img"
20+
submit_button_captcha_locator = "//button[@type='submit']"
21+
success_message_locator = "//p[@class='_successMessage_s7q0j_1']"
22+
23+
24+
# GETTERS
25+
26+
def get_element(locator):
27+
"""Waits for an element to be clickable and returns it"""
28+
return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator)))
29+
30+
31+
# ACTIONS
32+
33+
def solver_captcha(image, apikey):
34+
"""
35+
Solves a captcha using the 2Captcha service and returns the solution code
36+
37+
Args:
38+
image (str): Path to the captcha image
39+
apikey (str): API key to access the 2Captcha service
40+
Returns:
41+
str: Captcha solution code, if successful, otherwise None
42+
"""
43+
solver = TwoCaptcha(apikey)
44+
try:
45+
result = solver.coordinates(image)
46+
print(f"Captcha solved. Coordinates received")
47+
return result['code']
48+
except Exception as e:
49+
print(f"An error occurred: {e}")
50+
return None
51+
52+
def get_image_canvas(locator):
53+
"""
54+
Gets the Base64 representation of an image displayed on a web page using canvas
55+
56+
Args:
57+
locator (str): CSS selector for locating an image on a page
58+
Returns:
59+
str: Base64 image string
60+
"""
61+
62+
# JavaScript code to create a canvas, draw an image to the canvas and get its Base64 representation
63+
canvas_script = """
64+
function getBase64Image(imgElement) {
65+
let canvas = document.createElement('canvas');
66+
canvas.width = imgElement.width;
67+
canvas.height = imgElement.height;
68+
let ctx = canvas.getContext('2d');
69+
ctx.drawImage(imgElement, 0, 0);
70+
let base64Image = canvas.toDataURL();
71+
return base64Image;
72+
}
73+
return getBase64Image(document.querySelector(arguments[0]));
74+
"""
75+
base63_image = browser.execute_script(canvas_script, locator)
76+
return base63_image
77+
78+
def pars_coordinates(answer_to_captcha):
79+
"""
80+
Parses the coordinates from the captcha solution string.
81+
82+
Args:
83+
answer_to_captcha (str): Captcha solution string containing coordinates.
84+
Returns:
85+
list: List of dictionaries with 'x' and 'y' coordinates.
86+
"""
87+
# We remove the "coordinates:" prefix and split the line at the ";" symbol.
88+
coordinate_pairs = answer_to_captcha.replace("coordinates:", "").split(";")
89+
# Creating a list of dictionaries
90+
coordinates_list = []
91+
92+
for pair in coordinate_pairs:
93+
# We split each pair of coordinates by a comma and then by the "=" sign.
94+
coords = pair.split(",")
95+
coord_dict = {
96+
"x": int(coords[0].split("=")[1]),
97+
"y": int(coords[1].split("=")[1])
98+
}
99+
coordinates_list.append(coord_dict)
100+
101+
print("The received response is converted into a list of coordinates")
102+
return coordinates_list
103+
104+
def clicks_on_coordinates(coordinates_list, img_locator_captcha):
105+
"""
106+
Clicks on the specified coordinates within the image element using ActionChains.
107+
108+
Args:
109+
coordinates_list (list): List of dictionaries with 'x' and 'y' coordinates.
110+
img_locator_captcha (str): XPath locator of the image element.
111+
"""
112+
action = ActionChains(browser)
113+
114+
img_element = get_element(img_locator_captcha)
115+
116+
# Getting the initial coordinates of the image element
117+
location = img_element.location
118+
img_x = location['x']
119+
img_y = location['y']
120+
121+
for coord in coordinates_list:
122+
123+
# Calculate absolute coordinates on the page
124+
x_offset = img_x + coord['x']
125+
y_offset = img_y + coord['y']
126+
127+
# Click on the calculated coordinates
128+
action.move_by_offset(x_offset, y_offset).click().perform()
129+
130+
# We return the cursor back so as not to move the next clicks
131+
action.move_by_offset(-x_offset, -y_offset)
132+
133+
print('The coordinates are marked on the image')
134+
135+
def click_check_button(locator):
136+
"""
137+
Clicks the check button on a web page
138+
Args:
139+
locator (str): XPATH locator of the captcha verification button
140+
"""
141+
button = get_element(locator)
142+
button.click()
143+
print("Pressed the Check button")
144+
145+
def final_message(locator):
146+
"""
147+
Retrieves and prints the final success message.
148+
149+
Args:
150+
locator (str): The XPath locator of the success message.
151+
"""
152+
message = get_element(locator).text
153+
print(message)
154+
155+
# MAIN LOGIC
156+
157+
# Automatically closes the browser after block execution completes
158+
with webdriver.Chrome() as browser:
159+
# Go to page with captcha
160+
browser.get(url)
161+
print("Started")
162+
163+
# Getting captcha image in base64 format
164+
image_base64 = get_image_canvas(img_locator_captcha_for_get)
165+
166+
answer_to_captcha = solver_captcha(image_base64, apikey)
167+
168+
if answer_to_captcha:
169+
170+
coordinates_list = pars_coordinates(answer_to_captcha)
171+
172+
clicks_on_coordinates(coordinates_list, img_locator_captcha_for_click)
173+
174+
click_check_button(submit_button_captcha_locator)
175+
176+
final_message(success_message_locator)
177+
178+
browser.implicitly_wait(5)
179+
print("Finished")
180+
else:
181+
print("Failed to solve captcha")
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.common.by import By
3+
from selenium.webdriver.support.wait import WebDriverWait
4+
from selenium.webdriver.support import expected_conditions as EC
5+
import os
6+
from twocaptcha import TwoCaptcha
7+
8+
9+
# CONFIGURATION
10+
11+
url = "https://2captcha.com/demo/normal"
12+
apikey = os.getenv('APIKEY_2CAPTCHA')
13+
14+
15+
# ADVANCED CAPTCHA OPTIONS
16+
17+
extra_options = {
18+
"numeric": 4,
19+
"minLen": 4,
20+
"maxLen": 10,
21+
"lang": "en"
22+
}
23+
24+
25+
# LOCATORS
26+
27+
img_locator = "//img[@class='_captchaImage_rrn3u_9']"
28+
input_captcha_locator = "//input[@id='simple-captcha-field']"
29+
submit_button_captcha_locator = "//button[@type='submit']"
30+
success_message_locator = "//p[@class='_successMessage_rrn3u_1']"
31+
32+
33+
# GETTERS
34+
35+
def get_element(locator):
36+
"""Waits for an element to be clickable and returns it"""
37+
return WebDriverWait(browser, 30).until(EC.element_to_be_clickable((By.XPATH, locator)))
38+
39+
40+
# ACTIONS
41+
42+
def solver_captcha(image, apikey, **extra_options):
43+
"""
44+
Solves a captcha using the 2Captcha service and returns the solution code
45+
46+
Args:
47+
image (str): Path to the captcha image
48+
apikey (str): API key to access the 2Captcha service
49+
Returns:
50+
str: Captcha solution code, if successful, otherwise None
51+
"""
52+
solver = TwoCaptcha(apikey)
53+
try:
54+
result = solver.normal(image, **extra_options)
55+
print(f"Captcha solved. Code: {result['code']}")
56+
return result['code']
57+
except Exception as e:
58+
print(f"An error occurred: {e}")
59+
return None
60+
61+
def get_image_base64(locator):
62+
"""
63+
Captures a screenshot of the element specified by the locator and returns it as a base64-encoded string.
64+
65+
Args:
66+
locator (str): The XPath locator of the image element.
67+
Returns:
68+
str: The base64-encoded screenshot of the image element.
69+
"""
70+
image_element = get_element(locator)
71+
base64_image = image_element.screenshot_as_base64
72+
return base64_image
73+
74+
def input_captcha_code(locator, code):
75+
"""
76+
Enters the captcha solution code into the input field on the web page
77+
Args:
78+
locator (str): XPATH locator of the captcha input field
79+
code (str): Captcha solution code
80+
"""
81+
input_field = get_element(locator)
82+
input_field.send_keys(code)
83+
print("Entered the answer to the captcha")
84+
85+
def click_check_button(locator):
86+
"""
87+
Clicks the check button on a web page
88+
Args:
89+
locator (str): XPATH locator of the captcha verification button
90+
"""
91+
button = get_element(locator)
92+
button.click()
93+
print("Pressed the Check button")
94+
95+
def final_message(locator):
96+
"""
97+
Retrieves and prints the final success message.
98+
99+
Args:
100+
locator (str): The XPath locator of the success message.
101+
"""
102+
message = get_element(locator).text
103+
print(message)
104+
105+
106+
# MAIN LOGIC
107+
108+
# Automatically closes the browser after block execution completes
109+
with webdriver.Chrome() as browser:
110+
# Go to page with captcha
111+
browser.get(url)
112+
print("Started")
113+
114+
# Getting captcha image in base64 format
115+
image_base64 = get_image_base64(img_locator)
116+
117+
# Solving captcha using 2Captcha
118+
code = solver_captcha(image_base64, apikey, **extra_options)
119+
120+
if code:
121+
# Entering captcha code
122+
input_captcha_code(input_captcha_locator, code)
123+
# Pressing the test button
124+
click_check_button(submit_button_captcha_locator)
125+
# Receiving and displaying a success message
126+
final_message(success_message_locator)
127+
128+
browser.implicitly_wait(5)
129+
print("Finished")
130+
else:
131+
print("Failed to solve captcha")
132+

0 commit comments

Comments
 (0)