puppeteer-pro
Version:
A simple puppeteer wrapper to enable useful plugins with ease
91 lines • 4.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SolveRecaptchasPlugin = void 0;
const axios_1 = require("axios");
const path = require("path");
const ghost_cursor_1 = require("ghost-cursor");
const __1 = require("../..");
const avoid_detection_1 = require("./../avoid.detection");
// eslint-disable-next-line @typescript-eslint/no-require-imports
const injection = require(path.resolve(`${__dirname}/injections`) + '/utils.js');
const randomBetween = (min, max) => Math.floor(Math.random() * (max - min)) + min;
class SolveRecaptchasPlugin extends __1.Plugin {
constructor(witAiAccessToken) {
super();
this.dependencies = [new avoid_detection_1.AvoidDetectionPlugin()];
this.witAiAccessToken = witAiAccessToken;
}
async waitForCaptcha(page, timeout) {
return page.waitForFunction(() => !!document.querySelector('iframe[src*="api2/anchor"]') &&
!!document.querySelector('iframe[src*="api2/bframe"]'), { timeout });
}
async hasCaptcha(page) {
return page.evaluate(() => !!document.querySelector('iframe[src*="api2/anchor"]') &&
!!document.querySelector('iframe[src*="api2/bframe"]'));
}
async solveRecaptcha(page) {
if (this.isStopped)
return;
if (!this.witAiAccessToken)
return;
if (!(await this.hasCaptcha(page)))
return;
const anchorFrame = page.frames().find(x => x.url().includes('api2/anchor'));
if (!anchorFrame)
return;
const cursor = (0, ghost_cursor_1.createCursor)(page);
async function waitForSelector(iframe, selector) {
await iframe.waitForFunction((_selector) => document.querySelector(_selector), {}, selector);
}
async function findAndClick(iframe, selector) {
await waitForSelector(iframe, selector);
const element = await iframe.$(selector);
if (!element)
return;
await sleep(randomBetween(1 * 1000, 3 * 1000));
await cursor.click(element);
}
let numTriesLeft = 5;
async function isFinished() {
if (--numTriesLeft === 0)
return true;
return anchorFrame === null || anchorFrame === void 0 ? void 0 : anchorFrame.evaluate(() => !!document.querySelector('.recaptcha-checkbox-checked'));
}
await findAndClick(anchorFrame, '#recaptcha-anchor');
const bframeFrame = page.frames().find(x => x.url().includes('api2/bframe'));
if (!bframeFrame)
return;
await findAndClick(bframeFrame, '.rc-button-audio');
while (!(await isFinished())) {
await waitForSelector(bframeFrame, '.rc-audiochallenge-tdownload-link');
const audioUrl = await bframeFrame.evaluate(async () => { var _a; return (_a = document.querySelector('.rc-audiochallenge-tdownload-link')) === null || _a === void 0 ? void 0 : _a.href; });
if (!audioUrl)
return;
const audioArray = await bframeFrame.evaluate(injection, audioUrl);
if (!audioArray)
return;
const audioBuffer = Buffer.from(new Int8Array(audioArray));
const response = await axios_1.default.post('https://api.wit.ai/speech?v=20220527', audioBuffer, {
headers: {
Authorization: `Bearer ${this.witAiAccessToken}`,
'Content-Type': 'audio/wav',
},
});
const data = typeof response.data === 'string' ? JSON.parse(response.data.split('\r\n').slice(-1)[0] || '{}') : response.data;
if (data === null || data === void 0 ? void 0 : data.text) {
const responseInput = await bframeFrame.$('#audio-response');
await (responseInput === null || responseInput === void 0 ? void 0 : responseInput.type(data.text));
await findAndClick(bframeFrame, '#recaptcha-verify-button');
await sleep(1000);
}
else {
await findAndClick(bframeFrame, '#recaptcha-reload-button');
}
}
}
}
exports.SolveRecaptchasPlugin = SolveRecaptchasPlugin;
function sleep(timeout) {
return new Promise(resolve => setTimeout(resolve, timeout));
}
//# sourceMappingURL=index.js.map