auto-captcha-solver
Version:
Automatically detect and solve various captcha types in Playwright & Puppeteer with 2Captcha/CapMonster Cloud integration
140 lines (127 loc) • 6.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.captchaDetect = captchaDetect;
async function captchaDetect(page, captchaInfo, retries = 6) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
if (captchaInfo.captchaType === 'Image To Text') {
return { type: 'Image To Text' };
}
if (captchaInfo.captchaType === 'Text Captcha') {
return { type: 'Text Captcha' };
}
const captchaData = await page.evaluate(`(function() {
function extractValue(src, delimiter) {
return src.includes(delimiter) ? src.split(delimiter)[1] : null;
}
const captchaTypes = [
{ name: 'reCAPTCHA v2', selector: '.g-recaptcha', attr: 'data-sitekey' },
{ name: 'reCAPTCHA v2 Invisible', selector: '.g-recaptcha[data-size="invisible"]', attr: 'data-sitekey' },
{ name: 'reCAPTCHA v3', selector: 'script[src^="https://www.google.com/recaptcha/api.js?render="]', attr: 'src', extractor: function(src) { return extractValue(src, 'render='); } },
{ name: 'hCaptcha', selector: '.h-captcha', attr: 'data-sitekey' },
{ name: 'Cloudflare Turnstile', selector: '.cf-turnstile', attr: 'data-sitekey' },
{ name: 'reCAPTCHA Enterprise', selector: 'script[src^="https://www.google.com/recaptcha/enterprise.js?render="]', attr: 'src', extractor: function(src) { return extractValue(src, 'render='); } }
];
const isPageEmpty = document.body.innerText.trim().length === 0;
if (isPageEmpty) {
return { type: 'Cloudflare CAPTCHA' };
}
for (var i = 0; i < captchaTypes.length; i++) {
var name = captchaTypes[i].name;
var selector = captchaTypes[i].selector;
var attr = captchaTypes[i].attr;
var extractor = captchaTypes[i].extractor;
var element = document.querySelector(selector);
if (element) {
return {
type: name,
siteKey: attr ? (extractor ? extractor(element.getAttribute(attr) || '') : element.getAttribute(attr)) : null
};
}
}
// Check for GeeTest Captcha
var geeTestScript = document.querySelector('script[src*="api.geetest.com/get.php"]');
if (geeTestScript) {
var src = new URL(geeTestScript.getAttribute('src'));
var gt = src.searchParams.get('gt');
var challenge = src.searchParams.get('challenge');
if (gt && challenge) {
return {
type: 'GeeTest Captcha',
gt: gt,
challenge: challenge
};
}
}
// Check for GeeTest V4 Captcha
const geeTestV4Script = document.querySelector('script[src*="gcaptcha4.geetest.com/load"]');
if (geeTestV4Script) {
const src = new URL(geeTestV4Script.getAttribute('src'));
const captchaId = src.searchParams.get('captcha_id'); // Extract only captcha_id
const riskType = src.searchParams.get('risk_type'); // Extract only risk_type
if (captchaId) {
return {
type: 'GeeTest V4 Captcha',
captchaId: captchaId,
riskType: riskType || ''
};
}
}
// Check for reCAPTCHA v2 or v2 Invisible inside an iframe
const recaptchaIframe = document.querySelector('iframe[src*="recaptcha/api2/anchor"]');
if (recaptchaIframe) {
const iframeSrc = recaptchaIframe.getAttribute('src');
const siteKeyMatch = iframeSrc ? iframeSrc.match(/k=([^&]+)/) : null;
if (siteKeyMatch) {
const isInvisible = iframeSrc.includes('size=invisible');
return {
type: isInvisible ? 'reCAPTCHA v2 Invisible' : 'reCAPTCHA v2',
siteKey: siteKeyMatch[1]
};
}
}
// Check for hCaptcha inside an iframe
var hCaptchaIframe = document.querySelector('iframe[src*="hcaptcha.com"]');
if (hCaptchaIframe) {
var hCaptchaSrc = hCaptchaIframe.getAttribute('src');
var hCaptchaMatch = hCaptchaSrc ? hCaptchaSrc.match(/sitekey=([^&]+)/) : null;
if (hCaptchaMatch) {
return { type: 'hCaptcha', siteKey: hCaptchaMatch[1] };
}
}
// Lemin CAPTCHA Detection
const leminScript = document.querySelector('script[src*="api.leminnow.com"]');
if (leminScript) {
const src = leminScript.getAttribute('src');
if (src) {
// Extract the CAPTCHA ID from the URL
const match = src.match(${/cropped\/([^/]+)\//});
if (match && match[1]) {
return { type: 'Lemin CAPTCHA', captchaId: match[1] };
}
}
}
// Check for MTCaptcha
if (window.mtcaptchaConfig?.sitekey) {
return { type: 'MTCaptcha', siteKey: window.mtcaptchaConfig.sitekey };
}
if (window.mtcaptcha?.getConfiguration()?.sitekey) {
return { type: 'MTCaptcha', siteKey: window.mtcaptcha.getConfiguration().sitekey };
}
return null;
})();`);
if (captchaData) {
console.log({ captchaData });
return captchaData;
}
}
catch (error) {
throw new Error(`❌ Error on attempt ${attempt}: ${error.message}`);
}
if (attempt < retries) {
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
return null;
}
//# sourceMappingURL=captcha-detect.js.map