GeeTest v3 devuelve tres valores después de resolver: geetest_challenge, geetest_validate y geetest_seccode. Inyectarlos correctamente en una sesión de automatización del navegador requiere comprender dónde los espera el sitio: campos de formulario ocultos, devoluciones de llamada de JavaScript o cargas útiles XHR. Aquí se explica cómo hacerlo en cada marco principal.
Lo que estás inyectando
CaptchaAI devuelve un resultado de tres partes:
{
"geetest_challenge": "a1b2c3d4e5...modified_challenge",
"geetest_validate": "abc123def456_validate",
"geetest_seccode": "abc123def456_validate|jordan"
}
Se deben inyectar los tres valores. Faltar alguno provoca un error de verificación.
Paso 1: extraer parámetros y resolver
Común a todos los marcos: extraiga gt y challenge, luego resuelva con CaptchaAI:
import requests
import time
def solve_geetest(gt, challenge, page_url):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "geetest",
"gt": gt,
"challenge": challenge,
"pageurl": page_url,
"json": 1
})
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"] # Returns dict with three values
raise TimeoutError("GeeTest solve timed out")
Paso 2: inyectar en Playwright (Python)
Extraer parámetros
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# Capture GeeTest registration response
geetest_data = {}
def capture_geetest(response):
if "register" in response.url and response.status == 200:
try:
data = response.json()
if "gt" in data and "challenge" in data:
geetest_data.update(data)
except Exception:
pass
page.on("response", capture_geetest)
page.goto("https://staging.example.com/qa-login")
page.wait_for_selector(".geetest_holder")
gt = geetest_data["gt"]
challenge = geetest_data["challenge"]
Inyectar solución
# Solve con CaptchaAI
solution = solve_geetest(gt, challenge, page.url)
# Method 1: Set hidden form fields
page.evaluate(f"""
const fields = {{
'geetest_challenge': '{solution["geetest_challenge"]}',
'geetest_validate': '{solution["geetest_validate"]}',
'geetest_seccode': '{solution["geetest_seccode"]}'
}};
for (const [name, value] of Object.entries(fields)) {{
let input = document.querySelector(`input[name="${{name}}"]`);
if (!input) {{
input = document.createElement('input');
input.type = 'hidden';
input.name = name;
document.querySelector('form').appendChild(input);
}}
input.value = value;
}}
""")
# Submit the form
page.click("#submit-button")
Método 2: activar la devolución de llamada de GeeTest
Algunos sitios utilizan la devolución de llamada de JavaScript de GeeTest en lugar de campos de formulario:
page.evaluate(f"""
// Find the GeeTest captcha object
if (window.captchaObj) {{
// Simulate a successful solve
const result = {{
geetest_challenge: '{solution["geetest_challenge"]}',
geetest_validate: '{solution["geetest_validate"]}',
geetest_seccode: '{solution["geetest_seccode"]}'
}};
// Override getValidate to return our solution
window.captchaObj.getValidate = function() {{ return result; }};
// Trigger the success callback
const successEvent = new Event('geetest_success');
document.dispatchEvent(successEvent);
}}
""")
Paso 3: Inyectar en Puppeteer (JavaScript)
const puppeteer = require('puppeteer');
async function solveAndInject() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
// Capture GeeTest params
let gt, challenge;
page.on('response', async (response) => {
if (response.url().includes('register') && response.status() === 200) {
try {
const data = await response.json();
if (data.gt && data.challenge) {
gt = data.gt;
challenge = data.challenge;
}
} catch (e) {}
}
});
await page.goto('https://staging.example.com/qa-login');
await page.waitForSelector('.geetest_holder');
// Solve con CaptchaAI (implementation from earlier)
const solution = await solveCaptcha(gt, challenge, page.url());
// Inject the three values
await page.evaluate((sol) => {
// Set hidden inputs
const form = document.querySelector('form');
['geetest_challenge', 'geetest_validate', 'geetest_seccode'].forEach(name => {
let input = document.querySelector(`input[name="${name}"]`);
if (!input) {
input = document.createElement('input');
input.type = 'hidden';
input.name = name;
form.appendChild(input);
}
input.value = sol[name];
});
}, solution);
await page.click('#submit-button');
}
Paso 4: inyectar selenio (Python)
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
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
# Wait for GeeTest widget
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CLASS_NAME, "geetest_holder"))
)
# Extract gt and challenge from the page
gt = driver.execute_script(
"return document.querySelector('[data-gt]')?.dataset.gt"
)
challenge = driver.execute_script(
"return document.querySelector('[data-challenge]')?.dataset.challenge"
)
# Solve con CaptchaAI
solution = solve_geetest(gt, challenge, driver.current_url)
# Inject via JavaScript
driver.execute_script(f"""
var fields = {{
'geetest_challenge': '{solution["geetest_challenge"]}',
'geetest_validate': '{solution["geetest_validate"]}',
'geetest_seccode': '{solution["geetest_seccode"]}'
}};
var form = document.querySelector('form');
for (var name in fields) {{
var input = document.querySelector('input[name="' + name + '"]');
if (!input) {{
input = document.createElement('input');
input.type = 'hidden';
input.name = name;
form.appendChild(input);
}}
input.value = fields[name];
}}
""")
driver.find_element(By.ID, "submit-button").click()
Manejo de envíos basados en XHR
Algunos sitios envían los resultados de GeeTest a través de XHR en lugar del formulario POST. Interceptar y modificar la solicitud:
# Playwright: Intercept the XHR and inject values
def handle_route(route):
if "login" in route.request.url and route.request.method == "POST":
# Modify the POST data to include our solution
post_data = route.request.post_data
# Add GeeTest values to the request
route.continue_(post_data=modified_data)
else:
route.continue_()
page.route("**/api/login**", handle_route)
Solución de problemas
| Problema | causa | Solución |
|---|---|---|
| "La validación de GeeTest falló" | Falta uno de los tres valores. | Verifique que los tres valores estén inyectados |
| El desafío expiró antes de la inyección | Demasiado tiempo entre la extracción y la resolución | Extrae y resuelve en rápida sucesión |
| El formulario se envía pero los valores no están incluidos. | Nombres de campos o selector de formulario incorrectos | Inspeccione el formulario real para encontrar los nombres correctos. |
| Devolución de llamada no activada | El sitio utiliza un nombre de devolución de llamada personalizado | Encuentra la devolución de llamada en las opciones de initGeetest |
| Valores inyectados pero el widget aún se muestra | Estado del widget no actualizado | Activar la devolución de llamada exitosa mediante programación |
Preguntas frecuentes
¿Necesito ocultar visualmente el widget GeeTest después de la inyección?
No. El estado visual del widget no afecta el envío del formulario. Mientras los tres valores estén en los datos del formulario, el servidor los valida independientemente de la apariencia del widget.
¿Puedo inyectar valores de GeeTest sin un navegador?
Sí, si el sitio acepta un POST HTTP directo con los tres valores. Intercepte el punto final de envío del formulario y envíe los valores a través de requests o cualquier cliente HTTP.
¿Por qué GeeTest utiliza tres valores separados en lugar de un token?
Los tres valores tienen diferentes propósitos: geetest_challenge rastrea la sesión, geetest_validate demuestra que el desafío se resolvió y geetest_seccode proporciona un hash para la detección de manipulaciones.
Artículos relacionados
- Resolver Geetest V3 Nodejs
- Resolviendo Geetest V3 Nodejs Captchaai
- Resolución de captcha de automatización del navegador móvil
Próximos pasos
Inyecte soluciones GeeTest en cualquier marco:obtenga su clave API CaptchaAIy empieza a resolver.