Tự động gửi biểu mẫu bao gồm các thử thách CAPTCHA bằng Selenium và CaptchaAI.
Thử thách
Các biểu mẫu web được bảo vệ bằng tính năng tự động hóa khối CAPTCHA. Cho dù bạn đang kiểm tra biểu mẫu liên hệ, gửi đơn đăng ký hay chạy quy trình công việc QA, bạn cần phải giải CAPTCHA trước khi biểu mẫu chấp nhận nội dung gửi của bạn.
Kiến trúc
┌────────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ Load Form │────▶│ Fill Fields │────▶│ Detect & │────▶│ Submit Form │
│ (Selenium) │ │ │ │ Solve │ │ │
│ │ │ │ │ CAPTCHA │ │ │
└────────────┘ └──────────────┘ └────────────┘ └──────────────┘
Thành phần cốt lõi
Trình giải CAPTCHA
import time
import requests
class FormCaptchaSolver:
BASE = "https://ocr.captchaai.com"
def __init__(self, api_key):
self.api_key = api_key
def solve(self, params, initial_wait=10):
params["key"] = self.api_key
params["json"] = 1
resp = requests.post(f"{self.BASE}/in.php", data=params).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
time.sleep(initial_wait)
for _ in range(60):
result = requests.get(
f"{self.BASE}/res.php",
params={"key": self.api_key, "action": "get", "id": task_id, "json": 1},
).json()
if result["request"] == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if result["status"] == 1:
return result["request"]
raise Exception(f"Solve error: {result['request']}")
raise TimeoutError("CAPTCHA solve timed out")
Trình phát hiện CAPTCHA
import re
from selenium.webdriver.common.by import By
class CaptchaDetector:
def __init__(self, driver):
self.driver = driver
def detect(self):
"""Detect CAPTCHA type on current page."""
html = self.driver.page_source
# Turnstile
turnstile = self.driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile, [data-sitekey]")
for el in turnstile:
if "cf-turnstile" in (el.get_attribute("class") or ""):
return "turnstile", el.get_attribute("data-sitekey")
# reCAPTCHA
recaptcha = self.driver.find_elements(By.CSS_SELECTOR, "[data-sitekey]")
if recaptcha:
sitekey = recaptcha[0].get_attribute("data-sitekey")
if "recaptcha" in html.lower():
return "recaptcha_v2", sitekey
# Image CAPTCHA
img = self.driver.find_elements(By.CSS_SELECTOR, "img[src*='captcha'], img.captcha")
if img:
return "image", img[0].get_attribute("src")
return "none", None
Công cụ tự động hóa biểu mẫu
import base64
import requests as req
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class FormAutomator:
def __init__(self, api_key):
self.solver = FormCaptchaSolver(api_key)
self.driver = webdriver.Chrome()
self.detector = CaptchaDetector(self.driver)
def fill_field(self, selector, value):
field = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, selector))
)
field.clear()
field.send_keys(value)
def select_option(self, selector, value):
from selenium.webdriver.support.ui import Select
select = Select(self.driver.find_element(By.CSS_SELECTOR, selector))
select.select_by_value(value)
def solve_captcha(self):
captcha_type, data = self.detector.detect()
page_url = self.driver.current_url
if captcha_type == "recaptcha_v2":
token = self.solver.solve({
"method": "userrecaptcha",
"googlekey": data,
"pageurl": page_url,
})
self.driver.execute_script(
f'document.querySelector("[name=g-recaptcha-response]").value = "{token}";'
)
return True
if captcha_type == "turnstile":
token = self.solver.solve({
"method": "turnstile",
"sitekey": data,
"pageurl": page_url,
})
self.driver.execute_script(
f'document.querySelector("[name=cf-turnstile-response]").value = "{token}";'
)
return True
if captcha_type == "image":
img_data = req.get(data).content
img_b64 = base64.b64encode(img_data).decode()
text = self.solver.solve({"method": "base64", "body": img_b64})
captcha_input = self.driver.find_element(
By.CSS_SELECTOR, "input[name*='captcha']"
)
captcha_input.clear()
captcha_input.send_keys(text)
return True
return False # No CAPTCHA detected
def submit_form(self, url, fields, submit_selector="button[type='submit']"):
"""
fields: list of (selector, value) tuples
"""
self.driver.get(url)
for selector, value in fields:
self.fill_field(selector, value)
self.solve_captcha()
submit = self.driver.find_element(By.CSS_SELECTOR, submit_selector)
submit.click()
return self.driver.current_url
def close(self):
self.driver.quit()
Ví dụ hoàn chỉnh: Biểu mẫu liên hệ
automator = FormAutomator("YOUR_API_KEY")
try:
result_url = automator.submit_form(
url="https://example.com/contact",
fields=[
("#name", "John Doe"),
("#email", "john@example.com"),
("#subject", "Sales inquiry"),
("#message", "I'd like to learn more about your services."),
],
submit_selector="#submit-btn",
)
print(f"Form submitted. Redirected to: {result_url}")
finally:
automator.close()
Xử lý nhiều loại biểu mẫu
Mẫu đăng nhập
result = automator.submit_form(
url="https://staging.example.com/qa-login",
fields=[
("#username", "testuser"),
("#password", "testpass123"),
],
submit_selector="#login-btn",
)
Mẫu đăng ký
result = automator.submit_form(
url="https://example.com/register",
fields=[
("#first-name", "Jane"),
("#last-name", "Smith"),
("#email", "jane@example.com"),
("#password", "SecurePass!123"),
("#confirm-password", "SecurePass!123"),
],
submit_selector="#register-btn",
)
Biểu mẫu tìm kiếm bằng CAPTCHA
result = automator.submit_form(
url="https://example.com/search",
fields=[
("#query", "python developer"),
("#location", "San Francisco"),
],
submit_selector="#search-btn",
)
Khắc phục sự cố
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Mã thông báo bị từ chối | Mã thông báo đã hết hạn trước khi gửi | Giải CAPTCHA cuối cùng, gửi ngay |
| Không tìm thấy trường | Tải trang động | Thêm sự chờ đợi rõ ràng |
| Đã phát hiện loại CAPTCHA sai | Nhiều phần tử CAPTCHA | Kiểm tra thứ tự phát hiện |
| Tải lại biểu mẫu sau khi gửi | Xác thực phía máy chủ không thành công | Kiểm tra tất cả các trường bắt buộc |
| Lệnh gọi lại reCAPTCHA không được kích hoạt | Cần gọi hàm callback | Sử dụng grecaptcha.execute() sau khi tiêm |
Câu hỏi thường gặp
Tôi có thể gửi biểu mẫu mà không cần trình duyệt không?
Đối với reCAPTCHA và Turnstile, bạn có thể giải CAPTCHA mà không cần trình duyệt và gửi qua HTTP POST. Nhưng nếu biểu mẫu sử dụng xác thực JavaScript thì cần có trình duyệt.
Làm cách nào để xử lý các biểu mẫu có nhiều CAPTCHA?
Một số biểu mẫu chỉ hiển thị CAPTCHA sau khi xác thực không thành công. Chạy lại solve_captcha() sau mỗi lần gửi.
Còn các biểu mẫu AJAX thì sao?
Đối với các lần gửi AJAX, hãy chặn yêu cầu XHR và đưa mã thông báo CAPTCHA vào trọng tải yêu cầu thay vì điền vào trường ẩn.
Hướng dẫn liên quan
Tự động hóa mọi hình thức —giải CAPTCHA bằng CaptchaAI.