Skip to content

Instantly share code, notes, and snippets.

@natanavra
Created October 18, 2020 09:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save natanavra/ac97b859403e13570ac9f1552220e9ab to your computer and use it in GitHub Desktop.
Save natanavra/ac97b859403e13570ac9f1552220e9ab to your computer and use it in GitHub Desktop.
2captcha puppeteer
const captchaApiKey = 'API_KEY';
async function solveCaptcha(page, { userAgent, proxy }) {
const hasCaptcha = await page.waitForSelector('#recaptcha', { timeout: 5000 }).catch(() => {});
if(!hasCaptcha) {
return { hasCaptcha };
}
captchaSolver.setApiKey(captchaApiKey);
// eslint-disable-next-line no-underscore-dangle
const { cookies } = await page._client.send('Network.getAllCookies');
const cookiesString = captchaSolver.cookiesToString(cookies);
await page.waitFor(1000);
const captchaParams = await captchaSolver.getCatpchaParams(page);
const captcha = await captchaSolver.getToken({
googlekey: captchaParams.sitekey,
datas: captchaParams.datas,
pageurl: captchaParams.url,
cookies: cookiesString,
userAgent,
proxy,
proxytype: 'HTTP',
});
const nextUrl = `${captchaParams.url}&g-recaptcha-response=${captcha.token}`;
const finalResponse = await page.goto(nextUrl);
if(finalResponse.status() === 200) {
await captchaSolver.reportAnswer(captcha.id, true);
return { hasCaptcha, solved: true };
}
await captchaSolver.reportAnswer(captcha.id, false);
return { hasCaptcha, solved: false };
}
const request = require('request-promise');
const api = {
in: 'http://2captcha.com/in.php',
res: 'http://2captcha.com/res.php',
key: 'YOUR_API_KEY',
};
let params = {};
function setApiKey(apiKey) {
api.key = apiKey;
}
function cookiesToString(cookies) {
const cookiesArray = cookies.map((cookie) => {
if(cookie.name !== 'test_cookie') {
return `${cookie.name}:${cookie.value}`;
}
return undefined;
});
return cookiesArray.join(';');
}
function getCatpchaParams(page) {
/* eslint-disable */
return page.evaluate(() => ({
sitekey: document.querySelector('#recaptcha').dataset.sitekey,
callback: document.querySelector('#recaptcha').dataset.callback,
datas: document.querySelector('#recaptcha').dataset.s,
q: document.querySelector('input[name=q]').value,
url: document.querySelector('#recaptcha').baseURI,
}));
/* eslint-enable */
}
const getAnswer = captchaId => new Promise((resolve, reject) => {
const qs = {
key: api.key,
json: 1,
action: 'get',
id: captchaId,
taskinfo: 1,
};
const options = {
uri: api.res,
qs,
json: true,
};
request(options)
.then((res) => {
if(res.status === 1) {
// console.log(res)
resolve(res);
} else {
reject(new Error(res.request));
}
})
.catch((e) => {
reject(e);
});
});
const submitCaptcha = () => new Promise((resolve, reject) => {
const qs = {
key: api.key,
json: 1,
method: 'userrecaptcha',
version: 'v2',
googlekey: params.googlekey,
pageurl: params.pageurl,
datas: params.datas,
proxy: params.proxy,
proxytype: params.proxytype,
cookies: params.cookies,
userAgent: params.userAgent,
};
const options = {
uri: api.in,
qs,
json: true,
};
request(options)
.then((res) => {
if(res.status === 1) {
resolve(res.request);
} else {
const msg = `${res.request}: ${res.error_text}`;
reject(new Error(msg));
}
})
.catch((e) => {
reject(e);
});
});
const solveMyCaptcha = captchaId => new Promise((resolve, reject) => {
const loop = setInterval(async () => {
try {
const answer = await getAnswer(captchaId);
clearInterval(loop);
resolve(answer);
} catch(e) {
if(e.message !== 'CAPCHA_NOT_READY') {
clearInterval(loop);
reject(e);
}
}
}, 5000);
});
const getToken = async (options) => {
params = options;
try {
const id = await submitCaptcha();
const cap = await solveMyCaptcha(id);
return {
token: cap.request,
id,
worker: cap.user_check,
cookies: cap.cookies,
};
} catch(e) {
throw e;
}
};
const reportAnswer = (id, success) => new Promise((resolve, reject) => {
const qs = {
key: api.key,
json: 1,
action: success ? 'reportgood' : 'reportbad',
id,
};
const options = {
uri: api.res,
qs,
json: true,
};
// console.log(options)
request(options)
.then((res) => {
if(res.status === 1) {
resolve(res.request);
} else {
reject(res.request);
}
})
.catch((e) => {
reject(e);
});
});
module.exports = {
setApiKey,
cookiesToString,
getCatpchaParams,
getToken,
reportAnswer,
};
@sTuffedParrrot
Copy link

do you have code where you send a call back with the result, and anyway you can convert code to c# or vb.net?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment