puppeteer-pro 1.4.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +14 -12
- package/plugins/anonymize.user.agent/index.d.ts +2 -0
- package/plugins/anonymize.user.agent/index.d.ts.map +1 -1
- package/plugins/anonymize.user.agent/index.js +9 -4
- package/plugins/anonymize.user.agent/index.js.map +1 -1
- package/plugins/solve.recaptcha/index.d.ts +0 -1
- package/plugins/solve.recaptcha/index.d.ts.map +1 -1
- package/plugins/solve.recaptcha/index.js +6 -19
- package/plugins/solve.recaptcha/index.js.map +1 -1
- package/plugins/solve.recaptcha/injections/utils.js +138 -125
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ const solver = PuppeteerPro.solveRecaptchas('WIT_AI_ACCESS_TOKEN');
|
|
|
43
43
|
|
|
44
44
|
## Passive Improvements
|
|
45
45
|
|
|
46
|
-
- There can be multiple request interception handlers for the same request. In such cases, the resulting response will prioritize [`respond`](https://github.com/puppeteer/puppeteer/blob/
|
|
46
|
+
- There can be multiple request interception handlers for the same request. In such cases, the resulting response will prioritize [`respond`](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#httprequestrespondresponse), followed by [`abort`](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#httprequestaborterrorcode), followed by [`continue`](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#httprequestcontinueoverrides). For example:
|
|
47
47
|
- If amongst 5 handlers, respond is called 1 time, abort is called 2 times and continue is called 2 times, the result will be `respond`. This will occur after the first respond is called and not when all handlers are finished.
|
|
48
48
|
- If amongst 5 handlers, abort is called 1 time and continue is called 4 times, the result will be `abort`. This will occur after all handlers are finished.
|
|
49
49
|
- If amongst 5 handlers, all handlers call continue, the result will be `continue`. This will occur after all handlers are finished.
|
|
@@ -60,7 +60,7 @@ const solver = PuppeteerPro.solveRecaptchas('WIT_AI_ACCESS_TOKEN');
|
|
|
60
60
|
|
|
61
61
|
### Block Resources
|
|
62
62
|
|
|
63
|
-
- Block any [resource type](https://github.com/puppeteer/puppeteer/blob/
|
|
63
|
+
- Block any [resource type](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#httprequestresourcetype) from loading
|
|
64
64
|
- Can be used to speed up loading websites by blocking style sheets and images
|
|
65
65
|
|
|
66
66
|
### Disable Dialogs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "puppeteer-pro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "A simple puppeteer wrapper to enable useful plugins with ease",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,20 +34,22 @@
|
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=10.0.0"
|
|
36
36
|
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"axios": "^0.25.0",
|
|
39
|
+
"ghost-cursor": "^1.1.6",
|
|
40
|
+
"user-agents": "^1.0.907"
|
|
41
|
+
},
|
|
37
42
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^17.0.12",
|
|
44
|
+
"@types/user-agents": "^1.0.2",
|
|
39
45
|
"chai": "^4.3.4",
|
|
40
|
-
"copyfiles": "^2.
|
|
46
|
+
"copyfiles": "^2.4.1",
|
|
41
47
|
"dotenv-safe": "^8.2.0",
|
|
42
|
-
"eslint": "^7.
|
|
43
|
-
"mocha": "^9.0
|
|
44
|
-
"puppeteer": "^
|
|
48
|
+
"eslint": "^8.7.0",
|
|
49
|
+
"mocha": "^9.2.0",
|
|
50
|
+
"puppeteer": "^13.1.2",
|
|
45
51
|
"rimraf": "^3.0.2",
|
|
46
|
-
"tslint": "^6.1.
|
|
47
|
-
"typescript": "^4.
|
|
48
|
-
},
|
|
49
|
-
"dependencies": {
|
|
50
|
-
"axios": "^0.21.1",
|
|
51
|
-
"ghost-cursor": "^1.1.6"
|
|
52
|
+
"tslint": "^6.1.3",
|
|
53
|
+
"typescript": "^4.5.5"
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -2,6 +2,8 @@ import * as Puppeteer from 'puppeteer';
|
|
|
2
2
|
import { Plugin } from '../../index';
|
|
3
3
|
export declare class AnonymizeUserAgentPlugin extends Plugin {
|
|
4
4
|
private pages;
|
|
5
|
+
private userAgent?;
|
|
6
|
+
constructor();
|
|
5
7
|
protected afterLaunch(browser: Puppeteer.Browser): Promise<void>;
|
|
6
8
|
protected onClose(): Promise<void>;
|
|
7
9
|
protected onPageCreated(page: Puppeteer.Page): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/anonymize.user.agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/anonymize.user.agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUrC,qBAAa,wBAAyB,SAAQ,MAAM;IAClD,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAS;;cAaX,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO;cAStC,OAAO;cAIP,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;cASlC,aAAa;cAQb,SAAS;CAO1B"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
2
|
exports.AnonymizeUserAgentPlugin = void 0;
|
|
3
|
+
const UserAgent = require("user-agents");
|
|
3
4
|
const index_1 = require("../../index");
|
|
4
5
|
const sleep = (time) => { return new Promise(resolve => { setTimeout(resolve, time); }); };
|
|
5
6
|
class AnonymizeUserAgentPlugin extends index_1.Plugin {
|
|
6
7
|
constructor() {
|
|
7
|
-
super(
|
|
8
|
+
super();
|
|
8
9
|
this.pages = [];
|
|
10
|
+
try {
|
|
11
|
+
this.userAgent = new UserAgent({ vendor: 'Google Inc.', platform: 'Win32' }).toString();
|
|
12
|
+
}
|
|
13
|
+
catch (ex) {
|
|
14
|
+
console.warn('Could not create a random user agent');
|
|
15
|
+
}
|
|
9
16
|
}
|
|
10
17
|
async afterLaunch(browser) {
|
|
11
18
|
const _newPage = browser.newPage;
|
|
@@ -20,9 +27,7 @@ class AnonymizeUserAgentPlugin extends index_1.Plugin {
|
|
|
20
27
|
}
|
|
21
28
|
async onPageCreated(page) {
|
|
22
29
|
const userAgent = await page.browser().userAgent();
|
|
23
|
-
const newUserAgent = userAgent
|
|
24
|
-
.replace('HeadlessChrome/', 'Chrome/')
|
|
25
|
-
.replace(/\(([^)]+)\)/, '(Windows NT 10.0; Win64; x64)');
|
|
30
|
+
const newUserAgent = this.userAgent || userAgent.replace('HeadlessChrome/', 'Chrome/').replace(/\(([^)]+)\)/, '(Windows NT 10.0; Win64; x64)');
|
|
26
31
|
this.pages.push({ target: page, userAgent, newUserAgent });
|
|
27
32
|
await page.setUserAgent(newUserAgent);
|
|
28
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/anonymize.user.agent/index.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/anonymize.user.agent/index.ts"],"names":[],"mappings":";;AACA,yCAA0C;AAE1C,uCAAqC;AAErC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,GAAG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAQnG,MAAa,wBAAyB,SAAQ,cAAM;IAIlD;QACE,KAAK,EAAE,CAAC;QAJF,UAAK,GAAoB,EAAE,CAAC;QAMlC,IAAI;YACF,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;SACzF;QACD,OAAO,EAAE,EAAE;YACT,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;SACtD;IACH,CAAC;IAES,KAAK,CAAC,WAAW,CAAC,OAA0B;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QACjC,OAAO,CAAC,OAAO,GAAG,KAAK,IAA6B,EAAE;YACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAmC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,OAAO;QACrB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,IAAoB;QAChD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,+BAA+B,CAAC,CAAC;QAE/I,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QAE3D,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAES,KAAK,CAAC,aAAa;QAC3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;YAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAAE,SAAS;YAErC,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SACnD;IACH,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;YAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAAE,SAAS;YAErC,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAChD;IACH,CAAC;CACF;AApDD,4DAoDC","sourcesContent":["import * as Puppeteer from 'puppeteer';\nimport UserAgent = require('user-agents');\n\nimport { Plugin } from '../../index';\n\nconst sleep = (time: number) => { return new Promise(resolve => { setTimeout(resolve, time); }); };\n\ninterface PageUserAgent {\n target: Puppeteer.Page;\n userAgent: string;\n newUserAgent: string;\n}\n\nexport class AnonymizeUserAgentPlugin extends Plugin {\n private pages: PageUserAgent[] = [];\n private userAgent?: string;\n\n constructor() {\n super();\n\n try {\n this.userAgent = new UserAgent({ vendor: 'Google Inc.', platform: 'Win32' }).toString();\n }\n catch (ex) {\n console.warn('Could not create a random user agent');\n }\n }\n\n protected async afterLaunch(browser: Puppeteer.Browser) {\n const _newPage = browser.newPage;\n browser.newPage = async (): Promise<Puppeteer.Page> => {\n const page = await _newPage.apply(browser);\n await sleep(100); // Sleep to allow user agent to set\n return page;\n };\n }\n\n protected async onClose() {\n this.pages = [];\n }\n\n protected async onPageCreated(page: Puppeteer.Page) {\n const userAgent = await page.browser().userAgent();\n const newUserAgent = this.userAgent || userAgent.replace('HeadlessChrome/', 'Chrome/').replace(/\\(([^)]+)\\)/, '(Windows NT 10.0; Win64; x64)');\n\n this.pages.push({ target: page, userAgent, newUserAgent });\n\n await page.setUserAgent(newUserAgent);\n }\n\n protected async beforeRestart() {\n for (const page of this.pages) {\n if (page.target.isClosed()) continue;\n\n await page.target.setUserAgent(page.newUserAgent);\n }\n }\n\n protected async afterStop() {\n for (const page of this.pages) {\n if (page.target.isClosed()) continue;\n\n await page.target.setUserAgent(page.userAgent);\n }\n }\n}\n"]}
|
|
@@ -5,7 +5,6 @@ export declare class SolveRecaptchaPlugin extends Plugin {
|
|
|
5
5
|
dependencies: AvoidDetectionPlugin[];
|
|
6
6
|
witAiAccessToken?: string;
|
|
7
7
|
constructor(witAiAccessToken: string);
|
|
8
|
-
protected onPageCreated(page: Puppeteer.Page): Promise<void>;
|
|
9
8
|
hasCaptcha(page: Puppeteer.Page): Promise<boolean>;
|
|
10
9
|
solveRecaptcha(page: Puppeteer.Page): Promise<void>;
|
|
11
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/solve.recaptcha/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAKlE,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,YAAY,yBAAgC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAEd,gBAAgB,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/solve.recaptcha/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAKlE,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,YAAY,yBAAgC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAEd,gBAAgB,EAAE,MAAM;IAK9B,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;IAI/B,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;CAgE1C"}
|
|
@@ -13,10 +13,6 @@ class SolveRecaptchaPlugin extends index_1.Plugin {
|
|
|
13
13
|
this.dependencies = [new index_2.AvoidDetectionPlugin()];
|
|
14
14
|
this.witAiAccessToken = witAiAccessToken;
|
|
15
15
|
}
|
|
16
|
-
async onPageCreated(page) {
|
|
17
|
-
if (!this.isStopped && !page.isClosed())
|
|
18
|
-
await page.evaluateOnNewDocument(injection);
|
|
19
|
-
}
|
|
20
16
|
async hasCaptcha(page) {
|
|
21
17
|
return page.evaluate(() => { var _a, _b; return !!((_b = (_a = document.querySelector('iframe[src*="api2/anchor"]')) === null || _a === void 0 ? void 0 : _a.contentDocument) === null || _b === void 0 ? void 0 : _b.querySelector('#recaptcha-anchor')); });
|
|
22
18
|
}
|
|
@@ -28,7 +24,7 @@ class SolveRecaptchaPlugin extends index_1.Plugin {
|
|
|
28
24
|
return;
|
|
29
25
|
if (!(await this.hasCaptcha(page)))
|
|
30
26
|
return;
|
|
31
|
-
const cursor = ghost_cursor_1.createCursor(page);
|
|
27
|
+
const cursor = (0, ghost_cursor_1.createCursor)(page);
|
|
32
28
|
async function waitForSelector(iframeUrlIncludes, selector) {
|
|
33
29
|
await page.waitForFunction((_iframeUrlIncludes, _selector) => { var _a, _b; return (_b = (_a = document.querySelector(`iframe[src*="${_iframeUrlIncludes}"]`)) === null || _a === void 0 ? void 0 : _a.contentDocument) === null || _b === void 0 ? void 0 : _b.querySelector(_selector); }, {}, iframeUrlIncludes, selector);
|
|
34
30
|
}
|
|
@@ -51,22 +47,13 @@ class SolveRecaptchaPlugin extends index_1.Plugin {
|
|
|
51
47
|
await findAndClick('api2/bframe', '.rc-button-audio');
|
|
52
48
|
while (!(await isFinished())) {
|
|
53
49
|
await waitForSelector('api2/bframe', '.rc-audiochallenge-tdownload-link');
|
|
54
|
-
const
|
|
50
|
+
const audioUrl = await page.evaluate(async () => {
|
|
55
51
|
var _a, _b, _c;
|
|
56
|
-
|
|
57
|
-
if (!audioUrl)
|
|
58
|
-
return null;
|
|
59
|
-
const audioResponse = await fetch(audioUrl, { referrer: '' });
|
|
60
|
-
const audio = await audioResponse.arrayBuffer();
|
|
61
|
-
const _audioBuffer = await window.normalizeAudio(audio);
|
|
62
|
-
const audioSlice = await window.sliceAudio({
|
|
63
|
-
audioBuffer: _audioBuffer,
|
|
64
|
-
start: 1.5,
|
|
65
|
-
end: _audioBuffer.duration - 1.5
|
|
66
|
-
});
|
|
67
|
-
const wav = window.audioBufferToWav(audioSlice);
|
|
68
|
-
return [...new Int8Array(wav)];
|
|
52
|
+
return (_c = (_b = (_a = document.querySelector('iframe[src*="api2/bframe"]')) === null || _a === void 0 ? void 0 : _a.contentDocument) === null || _b === void 0 ? void 0 : _b.querySelector('.rc-audiochallenge-tdownload-link')) === null || _c === void 0 ? void 0 : _c.href;
|
|
69
53
|
});
|
|
54
|
+
if (!audioUrl)
|
|
55
|
+
return;
|
|
56
|
+
const audioArray = await page.evaluate(injection, audioUrl);
|
|
70
57
|
if (!audioArray)
|
|
71
58
|
return;
|
|
72
59
|
const audioBuffer = Buffer.from(new Int8Array(audioArray));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/solve.recaptcha/index.ts"],"names":[],"mappings":";;AAAA,iCAA0B;AAC1B,6BAA6B;AAE7B,+CAA4C;AAE5C,uCAAqC;AACrC,sDAAkE;AAElE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,aAAa,CAAC,GAAG,WAAW,CAAC,CAAC,CAAA,uCAAuC;AACxH,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAElG,MAAa,oBAAqB,SAAQ,cAAM;IAI9C,YAAY,gBAAwB;QAClC,KAAK,EAAE,CAAC;QAJV,iBAAY,GAAG,CAAC,IAAI,4BAAoB,EAAE,CAAC,CAAC;QAK1C,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/solve.recaptcha/index.ts"],"names":[],"mappings":";;AAAA,iCAA0B;AAC1B,6BAA6B;AAE7B,+CAA4C;AAE5C,uCAAqC;AACrC,sDAAkE;AAElE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,aAAa,CAAC,GAAG,WAAW,CAAC,CAAC,CAAA,uCAAuC;AACxH,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AAElG,MAAa,oBAAqB,SAAQ,cAAM;IAI9C,YAAY,gBAAwB;QAClC,KAAK,EAAE,CAAC;QAJV,iBAAY,GAAG,CAAC,IAAI,4BAAoB,EAAE,CAAC,CAAC;QAK1C,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAoB;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,eAAC,OAAA,CAAC,CAAC,CAAA,MAAA,MAAA,QAAQ,CAAC,aAAa,CAAoB,4BAA4B,CAAC,0CAAE,eAAe,0CAAE,aAAa,CAAC,mBAAmB,CAAC,CAAA,CAAA,EAAA,CAAC,CAAC;IAC7J,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAoB;;QACvC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QACnC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO;QAE3C,MAAM,MAAM,GAAG,IAAA,2BAAY,EAAC,IAAI,CAAC,CAAC;QAElC,KAAK,UAAU,eAAe,CAAC,iBAAyB,EAAE,QAAgB;YACxE,MAAM,IAAI,CAAC,eAAe,CAAC,CAAC,kBAA0B,EAAE,SAAiB,EAAE,EAAE,eAAC,OAAA,MAAA,MAAA,QAAQ,CAAC,aAAa,CAAoB,gBAAgB,kBAAkB,IAAI,CAAC,0CAAE,eAAe,0CAAE,aAAa,CAAC,SAAS,CAAC,CAAA,EAAA,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QAC/O,CAAC;QAED,KAAK,UAAU,YAAY,CAAC,iBAAyB,EAAE,QAAgB;;YACrE,MAAM,eAAe,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;YAEnD,MAAM,OAAO,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,0CAAE,CAAC,CAAC,QAAQ,CAAC,CAAA,CAAC;YACxG,IAAI,CAAC,OAAO;gBAAE,OAAO;YAErB,MAAM,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAC/C,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,UAAU,UAAU;YACvB,IAAI,EAAE,YAAY,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,eAAC,OAAA,CAAC,CAAC,CAAA,MAAA,MAAA,QAAQ,CAAC,aAAa,CAAoB,4BAA4B,CAAC,0CAAE,eAAe,0CAAE,aAAa,CAAC,6BAA6B,CAAC,CAAA,CAAA,EAAA,CAAC,CAAC;QACvK,CAAC;QAED,MAAM,YAAY,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;QACvD,MAAM,YAAY,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;QAEtD,OAAO,CAAC,CAAC,MAAM,UAAU,EAAE,CAAC,EAAE;YAC5B,MAAM,eAAe,CAAC,aAAa,EAAE,mCAAmC,CAAC,CAAC;YAE1E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;;gBAC9C,OAAO,MAAA,MAAA,MAAA,QAAQ,CAAC,aAAa,CAAoB,4BAA4B,CAAC,0CAAE,eAAe,0CAAE,aAAa,CAAkB,mCAAmC,CAAC,0CAAE,IAAI,CAAC;YAC7K,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ;gBAAE,OAAO;YAEtB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAE5D,IAAI,CAAC,UAAU;gBAAE,OAAO;YAExB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAAM,sCAAsC,EAAE,WAAW,EAAE;gBAC1F,OAAO,EAAE;oBACP,eAAe,EAAE,UAAU,IAAI,CAAC,gBAAgB,EAAE;oBAClD,cAAc,EAAE,WAAW;iBAC5B;aACF,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;gBACtB,MAAM,aAAa,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,0CAAE,CAAC,CAAC,iBAAiB,CAAC,CAAA,CAAC;gBACnH,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAExC,MAAM,YAAY,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;gBAE9D,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;aACnB;iBAAM;gBACL,MAAM,YAAY,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;aAC/D;SACF;IACH,CAAC;CACF;AA7ED,oDA6EC;AAED,SAAS,KAAK,CAAC,OAAe;IAC5B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import axios from 'axios';\nimport * as path from 'path';\nimport * as Puppeteer from 'puppeteer';\nimport { createCursor } from 'ghost-cursor';\n\nimport { Plugin } from '../../index';\nimport { AvoidDetectionPlugin } from './../avoid.detection/index';\n\nconst injection = require(path.resolve(`${__dirname}/injections`) + '/utils.js');// tslint:disable-line: no-var-requires\nconst randomBetween = (min: number, max: number) => Math.floor(Math.random() * (max - min)) + min;\n\nexport class SolveRecaptchaPlugin extends Plugin {\n dependencies = [new AvoidDetectionPlugin()];\n witAiAccessToken?: string;\n\n constructor(witAiAccessToken: string) {\n super();\n this.witAiAccessToken = witAiAccessToken;\n }\n\n async hasCaptcha(page: Puppeteer.Page) {\n return page.evaluate(() => !!document.querySelector<HTMLIFrameElement>('iframe[src*=\"api2/anchor\"]')?.contentDocument?.querySelector('#recaptcha-anchor'));\n }\n\n async solveRecaptcha(page: Puppeteer.Page) {\n if (this.isStopped) return;\n if (!this.witAiAccessToken) return;\n if (!(await this.hasCaptcha(page))) return;\n\n const cursor = createCursor(page);\n\n async function waitForSelector(iframeUrlIncludes: string, selector: string) {\n await page.waitForFunction((_iframeUrlIncludes: string, _selector: string) => document.querySelector<HTMLIFrameElement>(`iframe[src*=\"${_iframeUrlIncludes}\"]`)?.contentDocument?.querySelector(_selector), {}, iframeUrlIncludes, selector);\n }\n\n async function findAndClick(iframeUrlIncludes: string, selector: string) {\n await waitForSelector(iframeUrlIncludes, selector);\n\n const element = await page.frames().find(frame => frame.url().includes(iframeUrlIncludes))?.$(selector);\n if (!element) return;\n\n await sleep(randomBetween(1 * 1000, 3 * 1000));\n await cursor.click(element);\n }\n\n let numTriesLeft = 5;\n async function isFinished() {\n if (--numTriesLeft === 0) return true;\n return page.evaluate(() => !!document.querySelector<HTMLIFrameElement>('iframe[src*=\"api2/anchor\"]')?.contentDocument?.querySelector('.recaptcha-checkbox-checked'));\n }\n\n await findAndClick('api2/anchor', '#recaptcha-anchor');\n await findAndClick('api2/bframe', '.rc-button-audio');\n\n while (!(await isFinished())) {\n await waitForSelector('api2/bframe', '.rc-audiochallenge-tdownload-link');\n\n const audioUrl = await page.evaluate(async () => {\n return document.querySelector<HTMLIFrameElement>('iframe[src*=\"api2/bframe\"]')?.contentDocument?.querySelector<HTMLLinkElement>('.rc-audiochallenge-tdownload-link')?.href;\n });\n\n if (!audioUrl) return;\n\n const audioArray = await page.evaluate(injection, audioUrl);\n\n if (!audioArray) return;\n\n const audioBuffer = Buffer.from(new Int8Array(audioArray));\n\n const response = await axios.post<any>('https://api.wit.ai/speech?v=20210701', audioBuffer, {\n headers: {\n 'Authorization': `Bearer ${this.witAiAccessToken}`,\n 'Content-Type': 'audio/wav'\n }\n });\n\n if (response.data.text) {\n const responseInput = await page.frames().find(frame => frame.url().includes('api2/bframe'))?.$('#audio-response');\n responseInput?.type(response.data.text);\n\n await findAndClick('api2/bframe', '#recaptcha-verify-button');\n\n await sleep(1000);\n } else {\n await findAndClick('api2/bframe', '#recaptcha-reload-button');\n }\n }\n }\n}\n\nfunction sleep(timeout: number) {\n return new Promise(resolve => setTimeout(resolve, timeout));\n}"]}
|
|
@@ -1,132 +1,145 @@
|
|
|
1
|
-
module.exports = () => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
module.exports = async (audioUrl) => {
|
|
2
|
+
// Credit to https://github.com/dessant/buster
|
|
3
|
+
const normalizeAudio = async function (buffer) {
|
|
4
|
+
const ctx = new AudioContext();
|
|
5
|
+
const audioBuffer = await ctx.decodeAudioData(buffer);
|
|
6
|
+
ctx.close();
|
|
7
|
+
|
|
8
|
+
const offlineCtx = new OfflineAudioContext(1, audioBuffer.duration * 16000, 16000);
|
|
9
|
+
const source = offlineCtx.createBufferSource();
|
|
10
|
+
source.connect(offlineCtx.destination);
|
|
11
|
+
source.buffer = audioBuffer;
|
|
12
|
+
source.start();
|
|
13
|
+
|
|
14
|
+
return offlineCtx.startRendering();
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const sliceAudio = function ({ audioBuffer, start, end }) {
|
|
18
|
+
const sampleRate = audioBuffer.sampleRate;
|
|
19
|
+
const channels = audioBuffer.numberOfChannels;
|
|
20
|
+
|
|
21
|
+
const startOffset = sampleRate * start;
|
|
22
|
+
const endOffset = sampleRate * end;
|
|
23
|
+
const frameCount = endOffset - startOffset;
|
|
24
|
+
|
|
25
|
+
const ctx = new AudioContext();
|
|
26
|
+
const audioSlice = ctx.createBuffer(channels, frameCount, sampleRate);
|
|
27
|
+
ctx.close();
|
|
28
|
+
|
|
29
|
+
const tempArray = new Float32Array(frameCount);
|
|
30
|
+
for (var channel = 0; channel < channels; channel++) {
|
|
31
|
+
audioBuffer.copyFromChannel(tempArray, channel, startOffset);
|
|
32
|
+
audioSlice.copyToChannel(tempArray, channel, 0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return audioSlice;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Credit to https://github.com/Jam3/audiobuffer-to-wav
|
|
39
|
+
const audioBufferToWav = function (buffer, opt) {
|
|
40
|
+
opt = opt || {};
|
|
41
|
+
|
|
42
|
+
var numChannels = buffer.numberOfChannels;
|
|
43
|
+
var sampleRate = buffer.sampleRate;
|
|
44
|
+
var format = opt.float32 ? 3 : 1;
|
|
45
|
+
var bitDepth = format === 3 ? 32 : 16;
|
|
46
|
+
|
|
47
|
+
var result;
|
|
48
|
+
if (numChannels === 2) {
|
|
49
|
+
result = _.interleave(buffer.getChannelData(0), buffer.getChannelData(1));
|
|
50
|
+
} else {
|
|
51
|
+
result = buffer.getChannelData(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return _.encodeWAV(result, format, sampleRate, numChannels, bitDepth);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const _ = {
|
|
58
|
+
encodeWAV: (samples, format, sampleRate, numChannels, bitDepth) => {
|
|
59
|
+
var bytesPerSample = bitDepth / 8;
|
|
60
|
+
var blockAlign = numChannels * bytesPerSample;
|
|
61
|
+
|
|
62
|
+
var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample);
|
|
63
|
+
var view = new DataView(buffer);
|
|
64
|
+
|
|
65
|
+
/* RIFF identifier */
|
|
66
|
+
_.writeString(view, 0, 'RIFF');
|
|
67
|
+
/* RIFF chunk length */
|
|
68
|
+
view.setUint32(4, 36 + samples.length * bytesPerSample, true);
|
|
69
|
+
/* RIFF type */
|
|
70
|
+
_.writeString(view, 8, 'WAVE');
|
|
71
|
+
/* format chunk identifier */
|
|
72
|
+
_.writeString(view, 12, 'fmt ');
|
|
73
|
+
/* format chunk length */
|
|
74
|
+
view.setUint32(16, 16, true);
|
|
75
|
+
/* sample format (raw) */
|
|
76
|
+
view.setUint16(20, format, true);
|
|
77
|
+
/* channel count */
|
|
78
|
+
view.setUint16(22, numChannels, true);
|
|
79
|
+
/* sample rate */
|
|
80
|
+
view.setUint32(24, sampleRate, true);
|
|
81
|
+
/* byte rate (sample rate * block align) */
|
|
82
|
+
view.setUint32(28, sampleRate * blockAlign, true);
|
|
83
|
+
/* block align (channel count * bytes per sample) */
|
|
84
|
+
view.setUint16(32, blockAlign, true);
|
|
85
|
+
/* bits per sample */
|
|
86
|
+
view.setUint16(34, bitDepth, true);
|
|
87
|
+
/* data chunk identifier */
|
|
88
|
+
_.writeString(view, 36, 'data');
|
|
89
|
+
/* data chunk length */
|
|
90
|
+
view.setUint32(40, samples.length * bytesPerSample, true);
|
|
91
|
+
if (format === 1) { // Raw PCM
|
|
92
|
+
_.floatTo16BitPCM(view, 44, samples);
|
|
93
|
+
} else {
|
|
94
|
+
_.writeFloat32(view, 44, samples);
|
|
34
95
|
}
|
|
35
96
|
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
opt = opt || {};
|
|
97
|
+
return buffer;
|
|
98
|
+
},
|
|
99
|
+
interleave: (inputL, inputR) => {
|
|
100
|
+
var length = inputL.length + inputR.length;
|
|
101
|
+
var result = new Float32Array(length);
|
|
42
102
|
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var format = opt.float32 ? 3 : 1;
|
|
46
|
-
var bitDepth = format === 3 ? 32 : 16;
|
|
103
|
+
var index = 0;
|
|
104
|
+
var inputIndex = 0;
|
|
47
105
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
result =
|
|
51
|
-
|
|
52
|
-
result = buffer.getChannelData(0);
|
|
106
|
+
while (index < length) {
|
|
107
|
+
result[index++] = inputL[inputIndex];
|
|
108
|
+
result[index++] = inputR[inputIndex];
|
|
109
|
+
inputIndex++;
|
|
53
110
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
view.
|
|
70
|
-
/* RIFF type */
|
|
71
|
-
_.writeString(view, 8, 'WAVE');
|
|
72
|
-
/* format chunk identifier */
|
|
73
|
-
_.writeString(view, 12, 'fmt ');
|
|
74
|
-
/* format chunk length */
|
|
75
|
-
view.setUint32(16, 16, true);
|
|
76
|
-
/* sample format (raw) */
|
|
77
|
-
view.setUint16(20, format, true);
|
|
78
|
-
/* channel count */
|
|
79
|
-
view.setUint16(22, numChannels, true);
|
|
80
|
-
/* sample rate */
|
|
81
|
-
view.setUint32(24, sampleRate, true);
|
|
82
|
-
/* byte rate (sample rate * block align) */
|
|
83
|
-
view.setUint32(28, sampleRate * blockAlign, true);
|
|
84
|
-
/* block align (channel count * bytes per sample) */
|
|
85
|
-
view.setUint16(32, blockAlign, true);
|
|
86
|
-
/* bits per sample */
|
|
87
|
-
view.setUint16(34, bitDepth, true);
|
|
88
|
-
/* data chunk identifier */
|
|
89
|
-
_.writeString(view, 36, 'data');
|
|
90
|
-
/* data chunk length */
|
|
91
|
-
view.setUint32(40, samples.length * bytesPerSample, true);
|
|
92
|
-
if (format === 1) { // Raw PCM
|
|
93
|
-
_.floatTo16BitPCM(view, 44, samples);
|
|
94
|
-
} else {
|
|
95
|
-
_.writeFloat32(view, 44, samples);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return buffer;
|
|
99
|
-
},
|
|
100
|
-
interleave: (inputL, inputR) => {
|
|
101
|
-
var length = inputL.length + inputR.length;
|
|
102
|
-
var result = new Float32Array(length);
|
|
103
|
-
|
|
104
|
-
var index = 0;
|
|
105
|
-
var inputIndex = 0;
|
|
106
|
-
|
|
107
|
-
while (index < length) {
|
|
108
|
-
result[index++] = inputL[inputIndex];
|
|
109
|
-
result[index++] = inputR[inputIndex];
|
|
110
|
-
inputIndex++;
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
113
|
-
},
|
|
114
|
-
writeFloat32: (output, offset, input) => {
|
|
115
|
-
for (var i = 0; i < input.length; i++, offset += 4) {
|
|
116
|
-
output.setFloat32(offset, input[i], true);
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
floatTo16BitPCM: (output, offset, input) => {
|
|
120
|
-
for (var i = 0; i < input.length; i++, offset += 2) {
|
|
121
|
-
var s = Math.max(-1, Math.min(1, input[i]));
|
|
122
|
-
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
writeString: (view, offset, string) => {
|
|
126
|
-
for (var i = 0; i < string.length; i++) {
|
|
127
|
-
view.setUint8(offset + i, string.charCodeAt(i));
|
|
128
|
-
}
|
|
111
|
+
return result;
|
|
112
|
+
},
|
|
113
|
+
writeFloat32: (output, offset, input) => {
|
|
114
|
+
for (var i = 0; i < input.length; i++, offset += 4) {
|
|
115
|
+
output.setFloat32(offset, input[i], true);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
floatTo16BitPCM: (output, offset, input) => {
|
|
119
|
+
for (var i = 0; i < input.length; i++, offset += 2) {
|
|
120
|
+
var s = Math.max(-1, Math.min(1, input[i]));
|
|
121
|
+
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
writeString: (view, offset, string) => {
|
|
125
|
+
for (var i = 0; i < string.length; i++) {
|
|
126
|
+
view.setUint8(offset + i, string.charCodeAt(i));
|
|
129
127
|
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const audioResponse = await fetch(audioUrl, { referrer: '' });
|
|
132
|
+
const audio = await audioResponse.arrayBuffer();
|
|
133
|
+
|
|
134
|
+
const _audioBuffer = await normalizeAudio(audio);
|
|
135
|
+
|
|
136
|
+
const audioSlice = sliceAudio({
|
|
137
|
+
audioBuffer: _audioBuffer,
|
|
138
|
+
start: 1.5,
|
|
139
|
+
end: _audioBuffer.duration - 1.5
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const wav = audioBufferToWav(audioSlice);
|
|
143
|
+
|
|
144
|
+
return [...new Int8Array(wav)];
|
|
132
145
|
};
|