Reputation: 21
I'm trying to automate access to a website that uses Cloudflare Turnstile. I've managed to get the token from cf-turnstile-response, but I don't know how to inject it to complete the challenge.
Context
With Google reCAPTCHA v2, I used to inject the token by accessing ___grecaptcha_cfg and running the callback. However, I can't find a similar way for Turnstile.
await page.waitForFunction(() => typeof ___grecaptcha_cfg !== 'undefined' && ___grecaptcha_cfg.clients);
const inyeccion_callback = await page.evaluate((recaptcha_token) => {
const clients = ___grecaptcha_cfg.clients;
for (const client of clients) {
if (typeof client.callback === 'function') {
client.callback(recaptcha_token);
}
}
}, recaptcha_token);
I haven't found how to access the Turnstile settings or run a similar callback. The token I get from resolution services (like 2Captcha) is already set as follows and I have manually confirmed that it is set:
document.querySelector('[name="cf-turnstile-response"]').value = 'TOKEN';
But once that is done I don't know how to call or verify that since the website in question doesn't have forms or buttons to validate, it just waits for it to be resolved to continue.
After injecting the Cloudflare Turnstile token into the cf-turnstile-response element I would like to know how to obtain and execute a callback to validate the entered token.
Upvotes: 0
Views: 782
Reputation: 1
You might want to trigger the form submission or any hidden validation after injecting the token. Here’s a quick way to do that using Puppeteer:
await page.evaluate(() => {
const event = new Event('submit', { bubbles: true });
const form = document.querySelector('form');
form.dispatchEvent(event);
});
details on handling Cloudflare Turnstile,check this
Upvotes: 0
Reputation: 1
Source: https://www.youtube.com/watch?v=5YhrMaFP4tY&t=315s
// inject.js
console.clear = () => console.log('Console was cleared');
const i = setInterval(() => {
if (window.turnstile) {
clearInterval(i);
window.turnstile.render = (a, b) => {
let params = {
sitekey: b.sitekey,
pageurl: window.location.href,
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent,
json: 1,
};
// we will intercept the message
console.log('intercepted-params:' + JSON.stringify(params));
window.cfCallback = b.callback;
return;
};
}
},5);
// index.js
const { chromium } = require('playwright');
const { Solver } = require('@2captcha/captcha-solver');
const solver = new Solver('Your twocaptcha API key');
const proxyServer = 'Proxy server'; // Proxy server manager
const proxyUser = 'Proxy user';
const prpxyPassword = 'Proxy Password';
const example = async () => {
const browser = await chromium.launch({
headless: false,
devtools: false,
proxy: { "server": proxyServer, "username": proxyUser, "password": prpxyPassword },
});
const context = await browser.newContext({ ignoreHTTPSErrors: true });
const page = await context.newPage();
await page.addInitScript({ path: './inject.js' });
page.on('console', async (msg) => {
const txt = msg.text();
if (txt.includes('intercepted-params:')) {
const params = JSON.parse(txt.replace('intercepted-params:', ''));
console.log(params);
try {
console.log(`Solving the captcha...`);
const res = await solver.cloudflareTurnstile(params);
console.log(`Solved the captcha ${res.id}`);
console.log(res);
await page.evaluate((token) => {
cfCallback(token);
}, res.data);
} catch (e) {
console.log(e.err);
return process.exit();
}
} else {
return;
}
});
await page.goto('site url');
await page.waitForTimeout(5000);
await page.reload({ waitUntil: "networkidle" });
console.log('Reloaded');
};
example();
Upvotes: 0
Reputation: 1
const responseSelector = "#AreaCaptacha input[id*='cf-chl-widget']";
await page.evaluate(
(selector, value) => {
document.querySelector(selector).style.display = 'block'
document.querySelector(selector).value = value;
},
responseSelector,
token
)
Upvotes: 0