updated captcha code

This commit is contained in:
2026-02-16 13:20:29 +01:00
parent 4ed259ca5a
commit 5ab46a8f57
14 changed files with 726 additions and 71 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

+5 -13
View File
@@ -1,15 +1,7 @@
DATE | TIME | WEBSITE | REASON
----------------------------------------------------------------------------------------------------
14/02/2026 | 22:41:09 | Dutch News Test (https://www.dut | CAPTCHA present: reCAPTCHA
14/02/2026 | 22:41:09 | Kulala Land (https://kulalaland. | No email field detected
14/02/2026 | 22:41:09 | sneakywholefoods (https://www.sn | Not a newsletter signup form
14/02/2026 | 22:46:37 | Gate6 (https://gate6.vn/) | Navigating frame was detached
14/02/2026 | 22:46:37 | Kulala Land (https://kulalaland. | Navigating frame was detached
14/02/2026 | 22:46:37 | sneakywholefoods (https://www.sn | Connection closed.
14/02/2026 | 23:00:22 | Site_1 (https://jubina.com/list) | Failure keyword detected: "verification"
14/02/2026 | 23:04:00 | Site_1 (https://jubina.com/list) | Submit failed: Execution context was destroyed, most likely because of a navigation.
15/02/2026 | 00:06:51 | Site_1 (https://jubina.com/list) | Form still visible after submission (likely failed)
15/02/2026 | 00:18:09 | Dutch News Test (https://www.dut | Form still visible after submission (likely failed)
15/02/2026 | 00:18:27 | Site_1 (https://jubina.com/list) | Form still visible after submission (likely failed)
15/02/2026 | 00:18:50 | Site_1 (https://jubina.com/list) | Form still visible after submission (likely failed)
15/02/2026 | 00:20:19 | Site_1 (https://jubina.com/list) | Form still visible after submission (likely failed)
15/02/2026 | 12:40:49 | Dutch News Test (https://www.dut | Form still visible after submission (likely failed)
15/02/2026 | 12:40:49 | Immaculate Vegan (https://immacu | Form still visible after submission (likely failed)
15/02/2026 | 12:40:49 | Gate6 (https://gate6.vn/) | Form still visible after submission (likely failed)
15/02/2026 | 12:40:49 | Kulala Land (https://kulalaland. | No email field detected
15/02/2026 | 12:40:49 | sneakywholefoods (https://www.sn | Not a newsletter signup form
+33 -27
View File
@@ -80,29 +80,56 @@ async function main() {
try {
console.log(`\nProcessing ${sitesToProcess.length} sites...\n`);
const allResults = [];
for (let i = 0; i < sitesToProcess.length; i++) {
const site = sitesToProcess[i];
console.log(`[${i + 1}/${sitesToProcess.length}]`);
const result = await processSite(browser, site, globalCreds, browserConfig, cliOptions.keepOpen, cliOptions.dryRun);
const siteResult = {
name: site.name,
url: site.url,
success: !result.siteFailed,
reason: result.failureReason || 'Success',
timestamp: new Date().toISOString()
};
allResults.push(siteResult);
if (result.siteFailed) {
failedSites.push({
name: site.name,
url: site.url,
reason: result.failureReason,
timestamp: new Date().toISOString()
});
failedSites.push(siteResult);
processedCount.failed++;
} else {
processedCount.success++;
}
// Write results after each site
const reportPath = path.join(__dirname, 'site_results.txt');
const now = new Date();
const dateStr = now.toLocaleDateString('en-GB');
const timeStr = now.toLocaleTimeString('en-GB');
let reportContent = '';
if (!fs.existsSync(reportPath)) {
reportContent = 'DATE | TIME | STATUS | WEBSITE | RESULT\n';
reportContent += '-'.repeat(110) + '\n';
}
const website = `${site.name} (${site.url})`.substring(0, 32).padEnd(32);
const status = siteResult.success ? 'SUCCESS' : 'FAILED';
reportContent += `${dateStr} | ${timeStr} | ${status} | ${website} | ${siteResult.reason}\n`;
fs.appendFileSync(reportPath, reportContent);
console.log(` -> Result written to site_results.txt`);
await new Promise(r => setTimeout(r, 1000));
}
console.log(`\n${'='.repeat(70)}`);
console.log(`Done: ${processedCount.success} success, ${processedCount.failed} failed`);
console.log(`Full results: site_results.txt`);
} catch(error) {
console.error('Fatal error:', error.message);
@@ -113,27 +140,6 @@ async function main() {
} else {
await browser.close();
}
if (failedSites.length > 0) {
const reportPath = path.join(__dirname, 'failed_sites.txt');
const now = new Date();
const dateStr = now.toLocaleDateString('en-GB');
const timeStr = now.toLocaleTimeString('en-GB');
let reportContent = '';
if (!fs.existsSync(reportPath)) {
reportContent = 'DATE | TIME | WEBSITE | REASON\n';
reportContent += '-'.repeat(100) + '\n';
}
for (const site of failedSites) {
const website = `${site.name} (${site.url})`.substring(0, 32).padEnd(32);
reportContent += `${dateStr} | ${timeStr} | ${website} | ${site.reason}\n`;
}
fs.appendFileSync(reportPath, reportContent);
console.log(`${failedSites.length} failed. See: failed_sites.txt`);
}
}
}
+284
View File
@@ -9,8 +9,10 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@2captcha/captcha-solver": "^1.3.2",
"@iarna/toml": "^2.2.5",
"2captcha": "^3.0.5-2",
"axios": "^1.13.5",
"commander": "^14.0.3",
"playwright": "^1.56.1",
"playwright-extra": "^4.3.6",
@@ -21,6 +23,15 @@
"tesseract.js": "^7.0.0"
}
},
"node_modules/@2captcha/captcha-solver": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@2captcha/captcha-solver/-/captcha-solver-1.3.2.tgz",
"integrity": "sha512-tSxkzOZwgcGkIAOXXrfYGw6fSGk2WU/4StT91mjGfQZL891UEc5pbmGqrX/7hru3UqR1R+AyGwHs7g+QLU8/sg==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.1"
}
},
"node_modules/@babel/code-frame": {
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
@@ -181,6 +192,23 @@
"node": ">=4"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.13.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/b4a": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.4.tgz",
@@ -326,6 +354,19 @@
"node": "*"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -396,6 +437,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
@@ -486,12 +539,35 @@
"node": ">= 14"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/devtools-protocol": {
"version": "0.0.1566079",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1566079.tgz",
"integrity": "sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==",
"license": "BSD-3-Clause"
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -525,6 +601,51 @@
"is-arrayish": "^0.2.1"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -630,6 +751,26 @@
"pend": "~1.2.0"
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -651,6 +792,22 @@
"node": ">=0.10.0"
}
},
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@@ -685,6 +842,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -694,6 +860,43 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
@@ -744,12 +947,63 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -953,6 +1207,15 @@
"node": ">=12"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/merge-deep": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz",
@@ -967,6 +1230,27 @@
"node": ">=0.10.0"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+2
View File
@@ -11,8 +11,10 @@
"license": "ISC",
"type": "commonjs",
"dependencies": {
"@2captcha/captcha-solver": "^1.3.2",
"@iarna/toml": "^2.2.5",
"2captcha": "^3.0.5-2",
"axios": "^1.13.5",
"commander": "^14.0.3",
"playwright": "^1.56.1",
"playwright-extra": "^4.3.6",
+87
View File
@@ -0,0 +1,87 @@
DATE | TIME | STATUS | WEBSITE | RESULT
--------------------------------------------------------------------------------------------------------------
15/02/2026 | 12:55:22 | SUCCESS | Dutch News Test (https://www.dut | Success
15/02/2026 | 12:55:27 | SUCCESS | Immaculate Vegan (https://immacu | Success
15/02/2026 | 12:55:30 | FAILED | Gate6 (https://gate6.vn/) | Navigating frame was detached
15/02/2026 | 12:55:31 | FAILED | Kulala Land (https://kulalaland. | Connection closed.
15/02/2026 | 12:56:00 | SUCCESS | Immaculate Vegan (https://immacu | Success
15/02/2026 | 13:05:01 | FAILED | Immaculate Vegan (https://immacu | hCaptcha solving failed
15/02/2026 | 13:07:45 | FAILED | Immaculate Vegan (https://immacu | hCaptcha solving failed
15/02/2026 | 13:10:49 | FAILED | Immaculate Vegan (https://immacu | hCaptcha solving failed
15/02/2026 | 13:18:48 | FAILED | Immaculate Vegan (https://immacu | hCaptcha solving failed
15/02/2026 | 13:25:45 | FAILED | Site_1 (https://immaculatevegan. | hCaptcha solving failed
15/02/2026 | 13:25:52 | SUCCESS | Site_2 (https://gate6.vn/) | Success
15/02/2026 | 13:26:27 | SUCCESS | Site_3 (https://www.sprintzeal.c | Success
15/02/2026 | 13:26:30 | FAILED | Site_4 (https://kulalaland.com/) | No email field detected
15/02/2026 | 13:26:35 | SUCCESS | Site_5 (https://www.goplaces.co. | Success
15/02/2026 | 13:26:43 | SUCCESS | Site_6 (https://www.fiftyfiftybo | Success
15/02/2026 | 13:26:47 | FAILED | Site_7 (https://jubina.com/blog) | No email field detected
15/02/2026 | 13:26:53 | FAILED | Site_8 (https://www.sneakywholef | Not a newsletter signup form
15/02/2026 | 13:26:58 | SUCCESS | Site_9 (https://vegnews.com/sign | Success
15/02/2026 | 13:27:04 | SUCCESS | Site_10 (https://yonayonabeerwor | Success
15/02/2026 | 13:27:21 | SUCCESS | Site_11 (https://www.louispowers | Success
15/02/2026 | 13:27:28 | SUCCESS | Site_12 (https://www.hairworthy. | Success
15/02/2026 | 13:27:34 | FAILED | Site_13 (https://endotaspa.com.a | Not a newsletter signup form
15/02/2026 | 13:27:39 | SUCCESS | Site_14 (https://prestigify.com/ | Success
15/02/2026 | 13:27:42 | FAILED | Site_15 (https://nobones.co/) | No email field detected
15/02/2026 | 13:28:01 | SUCCESS | Site_16 (https://www.sofamania.c | Success
15/02/2026 | 13:28:12 | FAILED | Site_17 (https://dimoradellebalz | CAPTCHA present: reCAPTCHA
15/02/2026 | 13:28:25 | SUCCESS | Site_18 (https://www.42photo.com | Success
15/02/2026 | 13:28:27 | FAILED | Site_19 (https://ifinishedmybase | Execution context was destroyed, most likely because of a navigation.
15/02/2026 | 13:28:30 | FAILED | Site_20 (https://tettixgames.com | Navigating frame was detached
15/02/2026 | 13:28:31 | FAILED | Site_21 (https://www.corinnekai. | Connection closed.
15/02/2026 | 13:29:19 | FAILED | Site_1 (https://immaculatevegan. | hCaptcha solving failed
15/02/2026 | 13:29:25 | SUCCESS | Site_2 (https://gate6.vn/) | Success
15/02/2026 | 13:29:31 | SUCCESS | Site_3 (https://www.sprintzeal.c | Success
15/02/2026 | 13:29:45 | FAILED | Site_4 (https://kulalaland.com/) | No email field detected
15/02/2026 | 13:29:50 | SUCCESS | Site_5 (https://www.goplaces.co. | Success
15/02/2026 | 13:30:06 | SUCCESS | Site_6 (https://www.fiftyfiftybo | Success
15/02/2026 | 13:30:09 | FAILED | Site_7 (https://jubina.com/blog) | No email field detected
15/02/2026 | 13:30:27 | FAILED | Site_8 (https://www.sneakywholef | Not a newsletter signup form
15/02/2026 | 13:30:38 | SUCCESS | Site_9 (https://vegnews.com/sign | Success
15/02/2026 | 13:30:43 | SUCCESS | Site_10 (https://yonayonabeerwor | Success
15/02/2026 | 13:30:47 | SUCCESS | Site_11 (https://www.louispowers | Success
15/02/2026 | 13:30:57 | SUCCESS | Site_12 (https://www.hairworthy. | Success
15/02/2026 | 13:31:03 | FAILED | Site_13 (https://endotaspa.com.a | Not a newsletter signup form
15/02/2026 | 13:31:14 | SUCCESS | Site_14 (https://prestigify.com/ | Success
15/02/2026 | 13:31:16 | FAILED | Site_15 (https://nobones.co/) | No email field detected
15/02/2026 | 13:31:22 | SUCCESS | Site_16 (https://www.sofamania.c | Success
15/02/2026 | 13:31:29 | FAILED | Site_17 (https://dimoradellebalz | CAPTCHA present: reCAPTCHA
15/02/2026 | 13:31:34 | SUCCESS | Site_18 (https://www.42photo.com | Success
15/02/2026 | 13:31:37 | FAILED | Site_19 (https://ifinishedmybase | Execution context was destroyed, most likely because of a navigation.
15/02/2026 | 13:31:41 | SUCCESS | Site_20 (https://tettixgames.com | Success
15/02/2026 | 13:31:48 | SUCCESS | Site_21 (https://www.corinnekai. | Success
15/02/2026 | 13:31:59 | SUCCESS | Site_22 (https://www.blendnwhip. | Success
15/02/2026 | 13:32:04 | FAILED | Site_23 (https://www.brookebowli | Submit failed: SyntaxError: Failed to execute 'querySelector' on 'Document': '.
' is not a valid selector.
15/02/2026 | 13:32:07 | FAILED | Site_24 (https://www.thatveganda | Submit failed: SyntaxError: Failed to execute 'querySelector' on 'Document': '.
' is not a valid selector.
15/02/2026 | 13:32:14 | SUCCESS | Site_25 (https://comhwa.org.au/b | Success
15/02/2026 | 13:32:18 | FAILED | Site_26 (https://hiutdenim.co.uk | Submit failed: Node is either not clickable or not an Element
15/02/2026 | 13:32:24 | SUCCESS | Site_27 (https://local-lovely.co | Success
15/02/2026 | 13:32:40 | FAILED | Site_28 (https://vituswholefoods | Submit failed: No element found for selector: button:nth-of-type(0)
15/02/2026 | 13:32:45 | SUCCESS | Site_29 (https://theoriginalshab | Success
15/02/2026 | 13:32:52 | FAILED | Site_30 (https://rothys.com/en-a | No email field detected
15/02/2026 | 13:32:59 | FAILED | Site_31 (https://www.trustbasket | Not a newsletter signup form
15/02/2026 | 13:33:02 | FAILED | Site_32 (https://chelseabrice.co | Submit failed: SyntaxError: Failed to execute 'querySelector' on 'Document': '.
' is not a valid selector.
15/02/2026 | 13:33:06 | SUCCESS | Site_33 (https://wolfsgamingblog | Success
15/02/2026 | 13:33:11 | FAILED | Site_34 (https://www.leadfuze.co | No email field detected
15/02/2026 | 13:33:16 | FAILED | Site_35 (https://thedefiant.io/) | No email field detected
15/02/2026 | 13:33:22 | FAILED | Site_36 (https://www.entrepreneu | No email field detected
15/02/2026 | 13:33:32 | SUCCESS | Site_37 (https://pantproject.com | Success
15/02/2026 | 13:33:38 | FAILED | Site_38 (https://www.terrebleu.c | No email field detected
15/02/2026 | 13:33:41 | FAILED | Site_39 (https://www.shopify.com | Failed to fill email: SyntaxError: Failed to execute 'querySelector' on 'Document': '#email-input-:Rdbh4ll5H1:' is not a valid selector.
15/02/2026 | 13:33:47 | SUCCESS | Site_40 (https://www.skooob.com/ | Success
15/02/2026 | 13:33:52 | SUCCESS | Site_41 (https://mremountain.com | Success
15/02/2026 | 13:34:06 | SUCCESS | Site_42 (https://uncommonjames.c | Success
15/02/2026 | 13:34:11 | FAILED | Site_43 (https://www.axios.com/s | CAPTCHA present: reCAPTCHA
15/02/2026 | 13:34:14 | FAILED | Site_44 (https://www.dietassassi | Submit failed: SyntaxError: Failed to execute 'querySelector' on 'Document': '.
' is not a valid selector.
15/02/2026 | 13:34:19 | SUCCESS | Site_45 (https://miriamporter.ca | Success
15/02/2026 | 13:34:23 | FAILED | Site_46 (https://uppercasemagazi | No email field detected
15/02/2026 | 13:34:29 | SUCCESS | Site_47 (https://www.mercadodasr | Success
15/02/2026 | 13:34:35 | SUCCESS | Site_48 (https://mybageecha.com/ | Success
15/02/2026 | 13:34:48 | FAILED | Site_49 (https://bebemoss.com/) | Submit failed: Node is either not clickable or not an Element
15/02/2026 | 13:34:50 | FAILED | Site_50 (https://linkwithin.com/ | net::ERR_CONNECTION_RESET at https://linkwithin.com/
15/02/2026 | 13:43:01 | FAILED | Immaculate Vegan (https://immacu | Navigating frame was detached
+190 -9
View File
@@ -2,8 +2,8 @@ const Tesseract = require('tesseract.js');
const https = require('https');
const http = require('http');
const TwoCaptcha = require('2captcha');
const solver = new TwoCaptcha.Solver('9ed0ef51badf9a017ac50aea413d8001');
const { Solver } = require('@2captcha/captcha-solver');
const solver = new Solver('9ed0ef51badf9a017ac50aea413d8001');
const CAPTCHA_PATTERNS = {
recaptcha: {
@@ -11,7 +11,7 @@ const CAPTCHA_PATTERNS = {
name: 'reCAPTCHA'
},
hcaptcha: {
selectors: ['.h-captcha', '[data-hcaptcha-sitekey]', 'iframe[src*="hcaptcha"]', '#hcaptcha'],
selectors: ['.h-captcha', '[data-hcaptcha-sitekey]', 'iframe[src*="hcaptcha"]', '#hcaptcha', '[data-sitekey*="hcaptcha"]', '.hcaptcha-checkbox'],
name: 'hCaptcha'
},
textCaptcha: {
@@ -220,21 +220,22 @@ async function solveSimpleCaptcha(page) {
}
console.log(' Sending to 2Captcha (human workers)...');
const result = await solver.imageCaptcha(imageData, {
const result = await solver.imageCaptcha({
body: imageData,
numeric: 0,
minLength: 1,
maxLength: 10,
min_len: 1,
max_len: 10,
phrase: 0,
caseSensitive: 1,
calc: 0,
lang: 'en'
});
console.log(` 2Captcha solved: "${result.data}"`);
console.log(` 2Captcha solved: "${result}"`);
return {
type: 'image',
answer: result.data.trim(),
originalText: result.data,
answer: result.trim(),
originalText: result,
service: '2captcha',
imageSrc: imageCaptchaInfo.src
};
@@ -282,9 +283,189 @@ async function solveSimpleCaptcha(page) {
return null;
}
async function solveHCaptcha(page, pageUrl) {
try {
// First, try to find and click the hCaptcha checkbox directly via JavaScript
console.log(` Attempting to click hCaptcha checkbox directly...`);
const clickResult = await page.evaluate(() => {
// Try multiple approaches to check the checkbox
const selectors = [
'#checkbox',
'.hcaptcha-checkbox',
'[class*="hcaptcha"]',
'[role="checkbox"]',
'div[aria-haspopup="true"]'
];
for (const selector of selectors) {
const el = document.querySelector(selector);
if (el) {
// Try clicking it
el.click();
// Also try setting aria-checked
el.setAttribute('aria-checked', 'true');
// Check if it has a checked state now
const checked = el.getAttribute('aria-checked');
return { clicked: true, selector: selector, ariaChecked: checked };
}
}
return { clicked: false };
});
console.log(` Click result:`, clickResult);
// Wait a moment and check if hCaptcha is now checked
await new Promise(r => setTimeout(r, 1500));
const hCaptchaChecked = await page.evaluate(() => {
const checkbox = document.querySelector('#checkbox, .hcaptcha-checkbox, [role="checkbox"]');
if (checkbox) {
return checkbox.getAttribute('aria-checked') === 'true';
}
return false;
});
if (hCaptchaChecked) {
console.log(` hCaptcha checkbox checked successfully!`);
return { type: 'hcaptcha', answer: 'clicked', service: 'direct-click' };
}
// If direct click didn't work, try 2Captcha API
console.log(` Direct click didn't work, trying 2Captcha API...`);
const hcaptchaInfo = await page.evaluate(() => {
// Look for sitekey in data attributes
const dataSelectors = [
'[data-hcaptcha-sitekey]',
'[data-sitekey]',
'.h-captcha',
'#hcaptcha',
'[class*="hcaptcha"]'
];
for (const selector of dataSelectors) {
const elements = document.querySelectorAll(selector);
for (const el of elements) {
const sitekey = el.getAttribute('data-hcaptcha-sitekey') || el.getAttribute('data-sitekey');
if (sitekey && sitekey.length > 10) {
return { sitekey: sitekey, selector: selector };
}
// Check parent chain
let parent = el.parentElement;
for (let i = 0; i < 5 && parent; i++) {
const parentKey = parent.getAttribute('data-hcaptcha-sitekey') || parent.getAttribute('data-sitekey');
if (parentKey && parentKey.length > 10) {
return { sitekey: parentKey, selector: selector };
}
parent = parent.parentElement;
}
}
}
// Look for hCaptcha iframe and get sitekey from URL
const iframe = document.querySelector('iframe[src*="hcaptcha"]');
if (iframe) {
const src = iframe.getAttribute('src') || '';
const match = src.match(/sitekey=([^&]+)/);
if (match && match[1]) {
return { sitekey: match[1], selector: 'iframe[src*="hcaptcha"]' };
}
}
// Fallback: search entire HTML for hCaptcha sitekey pattern
const html = document.documentElement.innerHTML;
const sitekeyMatch = html.match(/["']sitekey["']\s*[:=]\s*["']([a-zA-Z0-9_-]{20,})["']/);
if (sitekeyMatch && sitekeyMatch[1]) {
return { sitekey: sitekeyMatch[1], selector: 'html-content' };
}
// Look for hcap sitekey
const hcapMatch = html.match(/hcap[tT]cha.*?["']sitekey["']\s*[:=]\s*["']([a-zA-Z0-9_-]{20,})["']/);
if (hcapMatch && hcapMatch[1]) {
return { sitekey: hcapMatch[1], selector: 'html-script' };
}
return null;
});
if (!hcaptchaInfo) {
console.log(` hCaptcha not found on page`);
return null;
}
console.log(` Found hCaptcha sitekey: ${hcaptchaInfo.sitekey}`);
console.log(` Submitting to 2Captcha...`);
// Use new @2captcha/captcha-solver package with object syntax
const result = await solver.hcaptcha({
pageurl: pageUrl,
sitekey: hcaptchaInfo.sitekey
});
console.log(` hCaptcha solved: ${result}`);
// Try multiple methods to set the token
await page.evaluate((token) => {
// Method 1: Find textarea
const textarea = document.querySelector('textarea[name="h-captcha-response"]');
if (textarea) {
textarea.value = token;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.dispatchEvent(new Event('change', { bubbles: true }));
console.log(' Set token in textarea');
}
// Method 2: Find iframe and set directly
const iframe = document.querySelector('iframe[src*="hcaptcha"]');
if (iframe) {
try {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
const iframeTextarea = iframeDoc.querySelector('textarea[name="h-captcha-response"]');
if (iframeTextarea) {
iframeTextarea.value = token;
iframeTextarea.dispatchEvent(new Event('input', { bubbles: true }));
console.log(' Set token in iframe textarea');
}
} catch(e) {
console.log(' Cannot access iframe directly');
}
}
// Method 3: Set on any hCaptcha related element
document.querySelectorAll('[id*="hcaptcha"], [class*="hcaptcha"]').forEach(el => {
if (el.value !== undefined) el.value = token;
if (el.dataset.response) el.dataset.response = token;
});
}, result.data);
return {
type: 'hcaptcha',
answer: result.data,
service: '2captcha'
};
} catch (error) {
const errorMsg = error.message || '';
if (errorMsg.includes('ERROR_METHOD_CALL') || errorMsg.includes('Unexpected Error')) {
console.log(` ERROR: hCaptcha not supported by your 2Captcha API key`);
console.log(` Your API key may not include hCaptcha solving.`);
console.log(` Options:`);
console.log(` - Contact 2Captcha to add hCaptcha to your plan`);
console.log(` - Use an alternative service like CapSolver or Anti-Captcha`);
} else {
console.log(` hCaptcha solving failed: ${errorMsg}`);
}
return null;
}
}
module.exports = {
CAPTCHA_PATTERNS,
detectCaptcha,
solveSimpleCaptcha,
solveHCaptcha,
fetchImageAsBuffer
};
+48 -6
View File
@@ -1,7 +1,7 @@
const { generateRandomData, parseLocator } = require('./config');
const { detectFormFields } = require('./fields');
const { detectSubmitButton } = require('./submit');
const { detectCaptcha, solveSimpleCaptcha } = require('./captcha');
const { detectCaptcha, solveSimpleCaptcha, solveHCaptcha } = require('./captcha');
const { classifyNewsletterForm } = require('./classifier');
const { detectSubmissionResult } = require('./submission');
@@ -232,7 +232,7 @@ async function processSite(browser, site, globalCreds, browserConfig, keepOpen =
console.log(` Page navigated to: ${urlAfterSubmit}`);
}
submissionResult = await detectSubmissionResult(page);
submissionResult = await detectSubmissionResult(page, urlBeforeSubmit);
} catch (resultError) {
console.log(` Could not detect submission result: ${resultError.message}`);
submissionResult = { failure: false, success: false, signals: ['Could not determine - page may have redirected'] };
@@ -246,10 +246,52 @@ async function processSite(browser, site, globalCreds, browserConfig, keepOpen =
}
}
if (submissionResult.failure) {
siteFailed = true;
failureReason = failureReason || submissionResult.failureReason || 'Form submission failed';
console.error(` FAILED: ${submissionResult.failureReason}`);
// Check for hCaptcha on redirected pages (like /challenge)
const postSubmitCaptcha = await detectCaptcha(page);
const visibleHCaptcha = postSubmitCaptcha.filter(c => c.type === 'hcaptcha' && c.isVisible);
const hasChallengeRedirect = page.url().includes('/challenge') || page.url().includes('captcha');
if ((visibleHCaptcha.length > 0 || hasChallengeRedirect) && !dryRun) {
console.log(` hCaptcha/challenge detected - attempting to solve...`);
const hcaptchaResult = await solveHCaptcha(page, page.url());
if (hcaptchaResult && hcaptchaResult.answer) {
console.log(` hCaptcha solved - resubmitting form...`);
// Wait a moment for the token to be set
await new Promise(r => setTimeout(r, 500));
const resubmitSelector = await detectSubmitButton(page);
if (resubmitSelector) {
await page.click(resubmitSelector);
await new Promise(r => setTimeout(r, 3000));
const resubmitResult = await detectSubmissionResult(page, urlBeforeSubmit);
if (resubmitResult.success) {
console.log(` SUCCESS after hCaptcha solve!`);
siteFailed = false;
failureReason = '';
} else if (resubmitResult.failure) {
siteFailed = true;
failureReason = resubmitResult.failureReason || 'Failed after hCaptcha';
} else {
// Still unknown but hCaptcha was solved - assume success
console.log(` hCaptcha solved, result unknown - assuming success`);
siteFailed = false;
failureReason = '';
}
}
} else {
console.log(` Could not solve hCaptcha`);
siteFailed = true;
failureReason = 'hCaptcha solving failed';
}
} else if ((visibleHCaptcha.length > 0 || hasChallengeRedirect) && dryRun) {
console.log(` [DRY-RUN] Would solve hCaptcha/challenge`);
} else if (submissionResult.failure) {
if (siteFailed) {
console.error(` FAILED: ${submissionResult.failureReason}`);
}
} else if (submissionResult.success) {
console.log(` SUCCESS: Subscription appears to have succeeded`);
} else {
+27 -14
View File
@@ -1,5 +1,5 @@
async function detectSubmissionResult(page) {
const result = await page.evaluate(() => {
async function detectSubmissionResult(page, urlBeforeSubmit = null) {
const result = await page.evaluate((beforeUrl) => {
const results = {
success: false,
failure: false,
@@ -8,6 +8,11 @@ async function detectSubmissionResult(page) {
signals: []
};
// Check if URL changed significantly (often indicates success)
if (beforeUrl && window.location.href !== beforeUrl) {
results.signals.push(`URL changed from ${beforeUrl.split('?')[0]} to ${window.location.href.split('?')[0]}`);
}
const errorSelectors = [
'.error', '.Error', '.ERROR',
'[class*="error" i]',
@@ -47,7 +52,8 @@ async function detectSubmissionResult(page) {
'thank you', 'thanks for', 'successfully', 'subscribed', 'subscription confirmed',
'you are now', 'welcome', 'email confirmed', 'verification sent',
'check your email', 'confirm your email', 'almost done',
'signed up', 'signed up successfully', 'subscription successful'
'signed up', 'signed up successfully', 'subscription successful',
'almost there', 'confirm your subscription', 'verify your email'
];
for (const keyword of successKeywords) {
@@ -62,10 +68,11 @@ async function detectSubmissionResult(page) {
'incorrect', 'invalid captcha', 'wrong captcha', 'incorrect captcha',
'captcha incorrect', 'captcha invalid', 'captcha error',
'please complete the captcha', 'complete the captcha',
'try again', 'submission failed'
'try again', 'submission failed', 'email already exists',
'you have already subscribed', 'already registered'
];
if (!results.failure) {
if (!results.success) {
for (const keyword of failureKeywords) {
if (pageText.includes(keyword)) {
results.failure = true;
@@ -76,18 +83,24 @@ async function detectSubmissionResult(page) {
}
}
const formStillVisible = document.querySelector('form') !== null;
const emailInputStillVisible = document.querySelector('input[type="email"]') !== null ||
document.querySelector('input[name*="email" i]') !== null;
if (formStillVisible && emailInputStillVisible && !results.success) {
results.failure = true;
results.failureReason = results.failureReason || 'Form still visible after submission (likely failed)';
results.signals.push('Form still visible - submission may have failed');
// Only check form visibility if we haven't determined success/failure yet
if (!results.success && !results.failure) {
const formStillVisible = document.querySelector('form') !== null;
const emailInputStillVisible = document.querySelector('input[type="email"]') !== null ||
document.querySelector('input[name*="email" i]') !== null;
if (formStillVisible && emailInputStillVisible) {
// Form still visible but no explicit success/failure - could be either
results.signals.push('Form still visible but no explicit result - unknown');
} else if (!formStillVisible && !emailInputStillVisible) {
// Form disappeared - likely success
results.success = true;
results.signals.push('Form no longer visible - assuming success');
}
}
return results;
});
}, urlBeforeSubmit);
return result;
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

-1
View File
@@ -1 +0,0 @@
https://jubina.com/list
+50
View File
@@ -0,0 +1,50 @@
https://immaculatevegan.com/blogs/magazine
https://gate6.vn/
https://www.sprintzeal.com/
https://kulalaland.com/
https://www.goplaces.co.uk/
https://www.fiftyfiftybottles.com/
https://jubina.com/blog
https://www.sneakywholefoods.com/
https://vegnews.com/signup
https://yonayonabeerworks.com/
https://www.louispowersportsonline.com/
https://www.hairworthy.co.uk/
https://endotaspa.com.au/
https://prestigify.com/
https://nobones.co/
https://www.sofamania.com/
https://dimoradellebalze.com/en/restaurant/
https://www.42photo.com/
https://ifinishedmybasement.com/
https://tettixgames.com/
https://www.corinnekai.com/raw-honey-raw-self-newsletter/
https://www.blendnwhip.com/
https://www.brookebowlin.com/nuance-required
https://www.thatvegandad.net/
https://comhwa.org.au/blog/newsletters/
https://hiutdenim.co.uk/
https://local-lovely.com/
https://vituswholefoods.com/
https://theoriginalshabby.it/
https://rothys.com/en-au
https://www.trustbasket.com/
https://chelseabrice.com/
https://wolfsgamingblog.com/
https://www.leadfuze.com/blog/
https://thedefiant.io/
https://www.entrepreneur.com/
https://pantproject.com/
https://www.terrebleu.ca/
https://www.shopify.com/in/blog/shopify-stores
https://www.skooob.com/
https://mremountain.com/
https://uncommonjames.com/
https://www.axios.com/signup/tampa-bay
https://www.dietassassinista.com/blog/tag/African+Cuisine
https://miriamporter.ca/
https://uppercasemagazine.com/
https://www.mercadodasrosas.com/
https://mybageecha.com/
https://bebemoss.com/
https://linkwithin.com/
-1
View File
@@ -1 +0,0 @@
https://jubina.com/list
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B