Fix CAPTCHA detection to allow invisible reCAPTCHA
Invisible reCAPTCHA (size=invisible) fires on submit and usually passes automatically. Only block on visible CAPTCHA challenges. Also fix form detection to work without <form> wrapper elements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -32,7 +32,14 @@ export async function apply(page, job, formFiller) {
|
||||
const hasLogin = !!(document.querySelector('input[type="password"]') ||
|
||||
(text.includes('sign in') && text.includes('create account')) ||
|
||||
(text.includes('log in') && text.includes('register')));
|
||||
const hasCaptcha = !!(document.querySelector('iframe[src*="recaptcha"], iframe[src*="captcha"], [class*="captcha"]'));
|
||||
// Only block on visible CAPTCHAs — invisible reCAPTCHA (size=invisible) fires on submit and usually passes
|
||||
const captchaFrames = Array.from(document.querySelectorAll('iframe[src*="recaptcha"], iframe[src*="captcha"]'));
|
||||
const hasVisibleCaptcha = captchaFrames.some(f => {
|
||||
if (f.src.includes('size=invisible')) return false;
|
||||
const rect = f.getBoundingClientRect();
|
||||
return rect.width > 50 && rect.height > 50;
|
||||
});
|
||||
const hasCaptcha = hasVisibleCaptcha;
|
||||
const isClosed = text.includes('no longer accepting') || text.includes('position has been filled') ||
|
||||
text.includes('this job is no longer') || text.includes('job not found') ||
|
||||
text.includes('this position is closed') || text.includes('listing has expired');
|
||||
@@ -44,7 +51,8 @@ export async function apply(page, job, formFiller) {
|
||||
if (pageCheck.hasCaptcha) return { status: 'skipped_captcha', meta };
|
||||
|
||||
// Some pages land directly on the form; others need an Apply button click
|
||||
const hasFormAlready = await page.$('form input[type="text"], form input[type="email"], form textarea');
|
||||
// Check if we landed directly on a form (with or without <form> wrapper)
|
||||
const hasFormAlready = await page.$('input[type="text"], input[type="email"], textarea');
|
||||
if (!hasFormAlready) {
|
||||
const applyBtn = page.locator([
|
||||
'a:has-text("Apply Now")',
|
||||
@@ -76,7 +84,8 @@ export async function apply(page, job, formFiller) {
|
||||
// Re-check for blockers after click
|
||||
const postClick = await page.evaluate(() => ({
|
||||
hasLogin: !!document.querySelector('input[type="password"]'),
|
||||
hasCaptcha: !!document.querySelector('iframe[src*="recaptcha"], [class*="captcha"]'),
|
||||
hasCaptcha: Array.from(document.querySelectorAll('iframe[src*="recaptcha"], iframe[src*="captcha"]'))
|
||||
.some(f => !f.src.includes('size=invisible') && f.getBoundingClientRect().width > 50),
|
||||
})).catch(() => ({}));
|
||||
if (postClick.hasLogin) return { status: 'skipped_login_required', meta };
|
||||
if (postClick.hasCaptcha) return { status: 'skipped_captcha', meta };
|
||||
|
||||
Reference in New Issue
Block a user