Captcha-solver in Node.js: werkend voorbeeld met fetch (2026)
Een captcha-solver in Node.js is één HTTP-verzoek. Node 18 en nieuwer bevatten fetch, dus je hebt geen pakket nodig om de API aan te roepen. Stuur de sitekey en de paginaURL, wacht op de respons, en zet het token in het formulier. Deze gids laat de hele flow zien voor PopularCaptcha, dat Scarnox vandaag zonder proxy oplost.
Begin met gratis proefcredit, zonder creditcard en draai de code hieronder eerst tegen een testpagina.
Vereisten
- Node.js 18 of nieuwer (
node --version). - Een Scarnox-API-sleutel. Bewaar die in een omgevingsvariabele.
- De sitekey van de PopularCaptcha-widget van de pagina. Als je die nog niet hebt, zie hoe je de captcha-sitekey vindt.
De solvermodule
De module hieronder is één functie. Ze stuurt een verzoek naar de API met een Bearer-header, breekt af na 185 seconden, en gooit een fout wanneer errorId niet 0 is:
// solver.mjs
const API_URL = "https://api.scarnox.com/api/tasks/create";
export async function solveCaptcha(sitekey, pageUrl, { invisible = false } = {}) {
const body = {
captcha_type: "PopularCaptchaTaskProxyless",
site_key: sitekey,
site_url: pageUrl,
};
if (invisible) body.is_invisible = true;
const res = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCARNOX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(185_000), // de aanroep keert terug wanneer het token klaar is
});
const data = await res.json().catch(() => null);
if (!data) throw new Error(`HTTP ${res.status}: response was not JSON`);
if (data.errorId !== 0) {
throw new Error(`${data.errorCode}: ${data.errorDescription}`);
}
return data.solution.token;
}
Er is geen polling. Het verzoek blijft open totdat het token klaar is, en bij succes staat het token in solution.token.
Nieuwe pogingen
Een mislukte oplossing geeft errorId terug dat niet 0 is, en daarvoor word je niet belast. Een korte lus met nieuwe pogingen is genoeg voor tijdelijke fouten. Houd het aantal pogingen laag, zodat een kapotte sitekey of paginaURL geen tijd opeet:
export async function solveWithRetry(sitekey, pageUrl, attempts = 3) {
let lastError;
for (let i = 1; i <= attempts; i++) {
try {
return await solveCaptcha(sitekey, pageUrl);
} catch (err) {
lastError = err;
console.warn(`Attempt ${i} failed: ${err.message}`);
await new Promise((r) => setTimeout(r, 1000 * i));
}
}
throw lastError;
}
Voor een uitgebreider foutbeleid, zie foutafhandeling van de captcha-solver.
Het token indienen
Het token gaat in het formulierveld dat de site verwacht. De meeste PopularCaptcha-pagina's lezen h-captcha-response, en veel ook g-recaptcha-response. Stuur beide, voor de zekerheid:
// submit.mjs
import { solveWithRetry } from "./solver.mjs";
const pageUrl = "https://example.com/signup";
const token = await solveWithRetry("YOUR-SITEKEY-UUID", pageUrl);
const form = new URLSearchParams({
email: "you@example.com",
"h-captcha-response": token,
"g-recaptcha-response": token,
});
const res = await fetch(pageUrl, {
method: "POST",
body: form,
redirect: "manual",
});
console.log("Status:", res.status);
Uitvoeren met:
SCARNOX_API_KEY=scarnox_YOURAPIKEY node submit.mjs
Cookies en sessies
Gewone fetch bewaart geen cookies tussen verzoeken. Veel aanmeld- en zoekpagina's koppelen de captcha aan een sessiecookie, dus een token dat zonder de bijbehorende cookie wordt verstuurd kan worden afgewezen. Er zijn twee manieren om dat aan te pakken:
- Kopieer de waarden van
set-cookieuit de GET-respons en stuur ze terug bij de POST. - Gebruik een browserautomatiseringstool, die de sessie voor je bewaart. Zie captcha oplossen met Playwright en Puppeteer.
Kies de eerste wanneer het formulier eenvoudig is en de site niet veel JavaScript draait. Kies de tweede voor alles wat ingewikkelder is.
Een praktische controle: kijk na de POST naar de statuscode en de uiteindelijke URL. Een redirect naar een succespagina betekent meestal dat het token is geaccepteerd. Een pagina die de widget opnieuw toont betekent meestal dat het is afgewezen, of dat de cookie van de GET niet is meegekomen. Log de responsbody bij de eerste paar runs, zodat je ziet in welk geval je zit.
Timing
Het token verloopt na ongeveer twee minuten. Los op vlak bij het moment dat je verzendt. De gebruikelijke fout is oplossen aan het begin van een lange job en pas later verzenden. Los op, en verstuur dan meteen. Verlopen captchatokens behandelt dit uitgebreider.
Onzichtbare captchas
Als de widget van de pagina data-size="invisible" heeft, geef dan { invisible: true } mee. De functie stuurt dan is_invisible: true mee met het verzoek:
const token = await solveCaptcha("YOUR-SITEKEY-UUID", pageUrl, { invisible: true });
Als de pagina ook een callback aan de widget koppelt, moet het formulier mogelijk die functie aanroepen met het token. Lees het script van de pagina om hem te vinden. De gids over onzichtbare captcha behandelt de patronen.
Scrapen met de solver
Soms verschijnt de captcha op een pagina die je scrapet in plaats van op een formulier dat je verzendt. Hetzelfde patroon werkt: detecteer de widget in de HTML, los hem op, en verstuur hem daarna naar de URL waarnaar de widget post. Houd het aantal verzoeken laag en controleer eerst de voorwaarden van de site. Scrape verantwoord: respecteer robots.txt, vermijd persoonsgegevens die je niet nodig hebt, en beuk de server niet.
Prijzen
Scarnox rekent per geslaagde oplossing. Mislukte oplossingen worden niet in rekening gebracht. Voor actuele tarieven, zie de prijzenpagina. Om te beginnen, begin met gratis proefcredit, zonder creditcard.