changed to individual files instead one big ass script and added auto captcha solver functionality

This commit is contained in:
2026-02-14 22:35:36 +01:00
parent ae87077519
commit 8725f4ddde
12 changed files with 1158 additions and 567 deletions
+128
View File
@@ -0,0 +1,128 @@
const Tesseract = require('tesseract.js');
const CAPTCHA_PATTERNS = {
recaptcha: {
selectors: ['.g-recaptcha', '[data-sitekey]', 'iframe[src*="recaptcha"]', '#recaptcha'],
name: 'reCAPTCHA'
},
hcaptcha: {
selectors: ['.h-captcha', '[data-hcaptcha-sitekey]', 'iframe[src*="hcaptcha"]', '#hcaptcha'],
name: 'hCaptcha'
},
textCaptcha: {
selectors: ['input[name*="captcha"]', 'input[id*="captcha"]', '.captcha-input', '#captcha'],
name: 'Text CAPTCHA'
},
imageCaptcha: {
selectors: ['img[src*="captcha"]', '.captcha-image', '#captcha-image', 'img[alt*="captcha" i]'],
name: 'Image CAPTCHA'
},
mathCaptcha: {
selectors: ['.math-captcha', '[name*="math"]', 'input[placeholder*="math" i]'],
name: 'Math CAPTCHA'
}
};
async function detectCaptcha(page) {
const captchaInfo = await page.evaluate((patterns) => {
const results = [];
for (const [type, config] of Object.entries(patterns)) {
for (const selector of config.selectors) {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) {
results.push({
type: type,
name: config.name,
selector: selector,
count: elements.length
});
break;
}
}
}
return results;
}, CAPTCHA_PATTERNS);
return captchaInfo;
}
async function solveSimpleCaptcha(page) {
const mathSolution = await page.evaluate(() => {
const mathText = document.querySelector('.math-captcha, .captcha-question, [class*="math"]');
if (mathText) {
const text = mathText.textContent || '';
const match = text.match(/(\d+)\s*([+\-*/])\s*(\d+)/);
if (match) {
const [_, a, op, b] = match;
let result;
switch(op) {
case '+': result = parseInt(a) + parseInt(b); break;
case '-': result = parseInt(a) - parseInt(b); break;
case '*': result = parseInt(a) * parseInt(b); break;
case '/': result = Math.floor(parseInt(a) / parseInt(b)); break;
}
return { type: 'math', answer: result, text: text };
}
}
return null;
});
if (mathSolution) {
return mathSolution;
}
const imageCaptchaInfo = await page.evaluate(() => {
const selectors = [
'img[src*="captcha"]',
'.captcha-image img',
'#captcha-image',
'img[alt*="captcha" i]',
'img[class*="captcha" i]'
];
for (const selector of selectors) {
const img = document.querySelector(selector);
if (img && img.src) {
return { src: img.src, selector: selector };
}
}
return null;
});
if (imageCaptchaInfo) {
console.log(' Attempting OCR-based CAPTCHA solving...');
try {
const { data: { text } } = await Tesseract.recognize(
imageCaptchaInfo.src,
'eng',
{ logger: m => {} }
);
const cleanedText = text.replace(/[^a-zA-Z0-9]/g, '').trim();
if (cleanedText && cleanedText.length >= 3) {
console.log(` OCR read: "${cleanedText}"`);
return {
type: 'image',
answer: cleanedText,
originalText: text,
imageSrc: imageCaptchaInfo.src
};
}
} catch (ocrError) {
console.log(` OCR failed: ${ocrError.message}`);
}
return { type: 'image', message: 'Image CAPTCHA detected - OCR failed, manual solving required' };
}
return null;
}
module.exports = {
CAPTCHA_PATTERNS,
detectCaptcha,
solveSimpleCaptcha
};