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.
Chuẩn bị
Phần tiêu đề “Chuẩn bị”pip install requests selenium pillowexport YESCAPTCHA_CLIENT_KEY=your_client_keyCần cài Chrome. Selenium 4 sẽ tự động tải chromedriver phù hợp.
Quy trình
Phần tiêu đề “Quy trình”- Click ô checkbox. Checkbox nằm trong iframe có
title="reCAPTCHA"; hãy chuyển vào iframe đó rồi click#recaptcha-anchor. - 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”).
- Đọc câu hỏi. Phần chữ in đậm trong
.rc-imageselect-desc-wrapper strongchí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. - 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
srccủatd.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. - Nhận dạng. Gọi
createTaskvới loạiReCaptchaV2Classification, truyềnimagevàquestion. Thêm"confidence": 0.5thì ả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. - Click.
objectstrả 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áctdtương ứng. - 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. - Gửi biểu mẫu. Quay lại trang chính và click nút gửi.
Mã đầy đủ
Phần tiêu đề “Mã đầy đủ”"""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.pyEach recognized image is charged (see the price list). reCAPTCHA's page structure can change;adjust the selectors below if a step stops working."""import base64import ioimport osimport time
import requestsfrom PIL import Imagefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support import expected_conditions as ECfrom 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()Lưu ý
Phần tiêu đề “Lưu ý”- 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.
© YesCaptcha