Bỏ qua để đến nội dung
Trạng tháiBảng điều khiển

Hướng dẫn

Mô phỏng click nhận dạng hình ảnh reCAPTCHA v2 (Selenium)

Trang này được dịch máy từ bản tiếng Trung và có thể có sai sót. Nội dung theo bản tiếng Trung.

Bài hướng dẫn này dùng Selenium 4 mở trang demo reCAPTCHA của Google và hoàn thành bài kiểm tra hình ảnh trong trình duyệt thật: đọc câu hỏi và hình ảnh, giao cho nhận dạng hình ảnh reCAPTCHA v2 (ReCaptchaV2Classification) xác định cần click những ô nào, rồi mô phỏng click. So với cách lấy token, cách này hoàn thành xác minh ngay trong trình duyệt, phù hợp với các website có tỷ lệ token được chấp nhận thấp.

Nếu không muốn viết mã, bạn có thể dùng trực tiếp tiện ích trình duyệt, vì nó tự động click dựa trên cùng một API.

pip install requests selenium pillow
export YESCAPTCHA_CLIENT_KEY=your_client_key

Cần cài Chrome. Selenium 4 sẽ tự động tải chromedriver phù hợp.

  1. Click ô checkbox. Checkbox nằm trong iframe có title="reCAPTCHA"; hãy chuyển vào iframe đó rồi click #recaptcha-anchor.
  2. Chuyển sang iframe của câu hỏi. Câu hỏi nằm trong một iframe khác (title chứa “challenge”).
  3. Đọc câu hỏi. Phần chữ in đậm trong .rc-imageselect-desc-wrapper strong chính là đối tượng cần tìm, ví dụ “traffic lights”. API cần ID câu hỏi, vì vậy hãy dùng bảng đối chiếu để đổi tên thành ID (/m/015qff), xem ID câu hỏi. Giao diện trình duyệt bằng tiếng Anh là thuận tiện nhất để đối chiếu.
  4. Lấy hình ảnh. Các ô thực chất là các phần của cùng một ảnh lớn; hãy tải src của td.rc-imageselect-tile img. Với 9 ô (3x3), thu phóng về 300×300; với 16 ô (4x4), thu phóng về 450×450, rồi chuyển sang Base64.
  5. Nhận dạng. Gọi createTask với loại ReCaptchaV2Classification, truyền image và question. Thêm "confidence": 0.5 thì ảnh 3x3 sẽ trả về một lần tất cả các ô phù hợp, không cần xử lý các ảnh nhỏ xuất hiện sau khi click.
  6. Click. objects trả về là số thứ tự các ô, bắt đầu từ 0, từ trái sang phải, từ trên xuống dưới; hãy lần lượt click các td tương ứng.
  7. Xác minh. Click #recaptcha-verify-button. Nếu xuất hiện vòng câu hỏi mới, quay lại bước 3; khi cửa sổ câu hỏi đóng lại nghĩa là đã vượt qua.
  8. Gửi biểu mẫu. Quay lại trang chính và click nút gửi.
recaptcha_click_selenium.py
"""Click through a reCAPTCHA v2 image challenge with Selenium 4 and ReCaptchaV2Classification.
Flow: open the page -> click the checkbox -> read the target name and the grid image ->
ask YesCaptcha which tiles to click -> click them -> press Verify. Repeat if a new challenge appears.
Run: pip install requests selenium pillow
export YESCAPTCHA_CLIENT_KEY=your_client_key
python recaptcha_click_selenium.py
Each recognized image is charged (see the price list). reCAPTCHA's page structure can change;
adjust the selectors below if a step stops working.
"""
import base64
import io
import os
import time
import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
PAGE_URL = "https://www.google.com/recaptcha/api2/demo"
# Target names shown in the challenge (English UI) -> question IDs.
# Full list: https://docs.yescaptcha.com/en/tasks/recaptcha-classification/
QUESTION_IDS = {
"taxis": "/m/0pg52", "bus": "/m/01bjv", "buses": "/m/01bjv", "motorcycles": "/m/04_sv",
"tractors": "/m/013xlm", "chimneys": "/m/01jk_4", "crosswalks": "/m/014xcs",
"traffic lights": "/m/015qff", "bicycles": "/m/0199g", "parking meters": "/m/015qbp",
"cars": "/m/0k4j", "bridges": "/m/015kr", "boats": "/m/019jd", "palm trees": "/m/0cdl1",
"mountains or hills": "/m/09d_r", "fire hydrants": "/m/01pns0", "a fire hydrant": "/m/01pns0",
"stairs": "/m/01lynh",
}
def classify(image_b64, question):
task = {"type": "ReCaptchaV2Classification", "image": image_b64, "question": question, "confidence": 0.5}
data = requests.post(
"https://api.yescaptcha.com/createTask",
json={"clientKey": CLIENT_KEY, "task": task},
timeout=30,
).json()
if data.get("errorId"):
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"] # synchronous: the solution comes back right away
def grid_image_b64(url, size):
"""Download the challenge image and scale it to the standard size (300 for 3x3, 450 for 4x4)."""
img = Image.open(io.BytesIO(requests.get(url, timeout=30).content)).convert("RGB")
img = img.resize((size, size))
buf = io.BytesIO()
img.save(buf, format="JPEG")
return base64.b64encode(buf.getvalue()).decode()
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 15)
try:
driver.get(PAGE_URL)
# 1. Click the checkbox (inside the "reCAPTCHA" iframe)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[title="reCAPTCHA"]')))
wait.until(EC.element_to_be_clickable((By.ID, "recaptcha-anchor"))).click()
driver.switch_to.default_content()
# 2. Switch to the challenge iframe and solve rounds until it closes
wait.until(EC.frame_to_be_available_and_switch_to_it(
(By.XPATH, '//iframe[contains(@title, "challenge")]')))
for _ in range(5):
target = wait.until(EC.presence_of_element_located(
(By.CSS_SELECTOR, ".rc-imageselect-desc-wrapper strong"))).text.strip().lower()
question = QUESTION_IDS.get(target)
if not question:
print("unsupported target, reloading:", target)
driver.find_element(By.ID, "recaptcha-reload-button").click()
time.sleep(2)
continue
tiles = driver.find_elements(By.CSS_SELECTOR, "td.rc-imageselect-tile")
size = 450 if len(tiles) == 16 else 300
url = driver.find_element(By.CSS_SELECTOR, "td.rc-imageselect-tile img").get_attribute("src")
solution = classify(grid_image_b64(url, size), question)
for index in solution.get("objects", []):
tiles[index].click()
time.sleep(0.3)
time.sleep(1)
driver.find_element(By.ID, "recaptcha-verify-button").click()
time.sleep(3)
driver.switch_to.default_content()
frame = driver.find_element(By.XPATH, '//iframe[contains(@title, "challenge")]')
if not frame.is_displayed(): # challenge closed: passed
break
driver.switch_to.frame(frame)
driver.switch_to.default_content()
driver.find_element(By.ID, "recaptcha-demo-submit").click()
time.sleep(2)
print("passed" if "Verification Success" in driver.page_source else "not passed")
finally:
driver.quit()
  • Cấu trúc trang của reCAPTCHA thay đổi theo thời gian; khi các selector trong mã không còn hiệu lực, hãy điều chỉnh theo trang thực tế.
  • Mỗi lần nhận dạng một ảnh đều bị trừ điểm (giá xem tại nhận dạng hình ảnh reCAPTCHA v2). Các tác vụ xác minh thất bại sau khi click có thể được báo cáo trong vòng 1 giờ để yêu cầu hoàn điểm.
  • Nếu gặp câu hỏi không có trong bảng đối chiếu, bạn có thể nhấn nút làm mới để đổi câu khác, hoặc liên hệ bộ phận hỗ trợ để bổ sung.