puppeteer-pro 1.3.1 → 1.5.1
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 +16 -3
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +10 -1
- package/index.js.map +1 -1
- package/package.json +15 -8
- 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/avoid.detection/index.d.ts.map +1 -1
- package/plugins/avoid.detection/index.js +1 -4
- package/plugins/avoid.detection/index.js.map +1 -1
- package/plugins/avoid.detection/injections/chrome.runtime.js +1 -3
- package/plugins/avoid.detection/injections/console.debug.js +1 -3
- package/plugins/avoid.detection/injections/hairline.js +1 -3
- package/plugins/avoid.detection/injections/navigator.languages.js +1 -3
- package/plugins/avoid.detection/injections/navigator.permissions.js +1 -3
- package/plugins/avoid.detection/injections/navigator.plugins.js +1 -3
- package/plugins/avoid.detection/injections/navigator.webdriver.js +1 -3
- package/plugins/avoid.detection/injections/webgl.js +1 -3
- package/plugins/avoid.detection/injections/window.js +1 -3
- package/plugins/solve.recaptcha/index.d.ts +11 -0
- package/plugins/solve.recaptcha/index.d.ts.map +1 -0
- package/plugins/solve.recaptcha/index.js +82 -0
- package/plugins/solve.recaptcha/index.js.map +1 -0
- package/plugins/solve.recaptcha/injections/utils.js +145 -0
package/README.md
CHANGED
|
@@ -21,13 +21,21 @@ const PuppeteerPro = require('puppeteer-pro');
|
|
|
21
21
|
// Enable the 'avoidDetection' plugin to prevent headless detection
|
|
22
22
|
PuppeteerPro.avoidDetection();
|
|
23
23
|
|
|
24
|
+
// Enable the 'solveRecaptchas' plugin to solve Google's recaptchas (remember to provide a wit.api API access token)
|
|
25
|
+
const solver = PuppeteerPro.solveRecaptchas('WIT_AI_ACCESS_TOKEN');
|
|
26
|
+
|
|
24
27
|
(async () => {
|
|
25
28
|
const browser = await PuppeteerPro.launch();
|
|
26
29
|
const page = await browser.newPage();
|
|
27
30
|
|
|
28
31
|
console.log('Testing the 🐱👤 avoidDetection 🐱👤 plugin..')
|
|
29
32
|
await page.goto('https://arh.antoinevastel.com/bots/areyouheadless');
|
|
30
|
-
await page.screenshot({ path: '
|
|
33
|
+
await page.screenshot({ path: 'are-you-headless.png' });
|
|
34
|
+
|
|
35
|
+
console.log('Testing the recaptcha solver..')
|
|
36
|
+
await page.goto('https://www.google.com/recaptcha/api2/demo');
|
|
37
|
+
await solver.solveRecaptcha(page);
|
|
38
|
+
await page.screenshot({ path: 'is-recaptcha-solved.png' });
|
|
31
39
|
|
|
32
40
|
await browser.close();
|
|
33
41
|
})();
|
|
@@ -35,7 +43,7 @@ PuppeteerPro.avoidDetection();
|
|
|
35
43
|
|
|
36
44
|
## Passive Improvements
|
|
37
45
|
|
|
38
|
-
- 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:
|
|
39
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.
|
|
40
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.
|
|
41
49
|
- If amongst 5 handlers, all handlers call continue, the result will be `continue`. This will occur after all handlers are finished.
|
|
@@ -52,7 +60,7 @@ PuppeteerPro.avoidDetection();
|
|
|
52
60
|
|
|
53
61
|
### Block Resources
|
|
54
62
|
|
|
55
|
-
- 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
|
|
56
64
|
- Can be used to speed up loading websites by blocking style sheets and images
|
|
57
65
|
|
|
58
66
|
### Disable Dialogs
|
|
@@ -63,3 +71,8 @@ PuppeteerPro.avoidDetection();
|
|
|
63
71
|
|
|
64
72
|
- Save and load cookies across sessions
|
|
65
73
|
- Supports multiple profiles and switching between profiles
|
|
74
|
+
|
|
75
|
+
### Solve Recaptcha
|
|
76
|
+
|
|
77
|
+
- Solve Google's reCAPTCHA v2
|
|
78
|
+
- Requires a FREE [wit.ai](https://wit.ai/apps) access token
|
package/index.d.ts
CHANGED
|
@@ -40,4 +40,6 @@ import { DisableDialogsPlugin } from './plugins/disable.dialogs';
|
|
|
40
40
|
export declare function disableDialogs(logMessages?: boolean): DisableDialogsPlugin;
|
|
41
41
|
import { ManageCookiesPlugin, ManageCookiesOption } from './plugins/manage.cookies';
|
|
42
42
|
export declare function manageCookies(opts: ManageCookiesOption): ManageCookiesPlugin;
|
|
43
|
+
import { SolveRecaptchaPlugin } from './plugins/solve.recaptcha';
|
|
44
|
+
export declare function solveRecaptchas(accessToken: string): SolveRecaptchaPlugin;
|
|
43
45
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAIvC,wBAAsB,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAc5F;AAED,yIAAyI;AACzI,wBAAsB,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC,4BAA4B,GAAG,SAAS,CAAC,qBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAIvC,wBAAsB,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAc5F;AAED,yIAAyI;AACzI,wBAAsB,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC,4BAA4B,GAAG,SAAS,CAAC,qBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAgBrK;AAID,qBAAa,MAAM;IACjB,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAQ;IACnD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAK;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAM;IACtC,SAAS,CAAC,oBAAoB,UAAS;IAEvC,IAAI,aAAa,YAA+B;IAChD,IAAI,SAAS,YAAsC;cAEnC,aAAa,CAAC,MAAM,EAAE,MAAM;IAItC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO;cA6BrB,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO;cACvC,OAAO;cAEP,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM;cAwExC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI;cAEnC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW;cAOxC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW;cAE9C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM;cAQjC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM;cAEvC,aAAa;IACvB,OAAO;cAUG,YAAY;cAEZ,UAAU;IACpB,IAAI;cAkBM,SAAS;cAET,YAAY;CAS7B;AAGD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,QAA2B;AACnE,wBAAsB,YAAY,kBAMjC;AAED,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,wBAAgB,kBAAkB,IAAI,wBAAwB,CAI7D;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,wBAAgB,cAAc,IAAI,oBAAoB,CAIrD;AAED,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC3E,wBAAgB,cAAc,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAI7E;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,wBAAgB,cAAc,CAAC,WAAW,UAAQ,GAAG,oBAAoB,CAIxE;AAED,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpF,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,CAI5E;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,CAIzE"}
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
-
exports.manageCookies = exports.disableDialogs = exports.blockResources = exports.avoidDetection = exports.anonymizeUserAgent = exports.clearPlugins = exports.addPlugin = exports.Plugin = exports.launch = exports.connect = void 0;
|
|
2
|
+
exports.solveRecaptchas = exports.manageCookies = exports.disableDialogs = exports.blockResources = exports.avoidDetection = exports.anonymizeUserAgent = exports.clearPlugins = exports.addPlugin = exports.Plugin = exports.launch = exports.connect = void 0;
|
|
3
3
|
const events = require("events");
|
|
4
4
|
// Puppeteer Defaults
|
|
5
5
|
const Puppeteer = require("puppeteer");
|
|
@@ -19,6 +19,8 @@ async function connect(options) {
|
|
|
19
19
|
exports.connect = connect;
|
|
20
20
|
/** The method launches a browser instance with given arguments. The browser will be closed when the parent node.js process is closed. */
|
|
21
21
|
async function launch(options) {
|
|
22
|
+
if (!options)
|
|
23
|
+
options = {};
|
|
22
24
|
const browser = await Puppeteer.launch({ defaultViewport: undefined, ...options });
|
|
23
25
|
for (const plugin of plugins) {
|
|
24
26
|
await plugin.init(browser);
|
|
@@ -232,4 +234,11 @@ function manageCookies(opts) {
|
|
|
232
234
|
return plugin;
|
|
233
235
|
}
|
|
234
236
|
exports.manageCookies = manageCookies;
|
|
237
|
+
const solve_recaptcha_1 = require("./plugins/solve.recaptcha");
|
|
238
|
+
function solveRecaptchas(accessToken) {
|
|
239
|
+
const plugin = new solve_recaptcha_1.SolveRecaptchaPlugin(accessToken);
|
|
240
|
+
plugins.push(plugin);
|
|
241
|
+
return plugin;
|
|
242
|
+
}
|
|
243
|
+
exports.solveRecaptchas = solveRecaptchas;
|
|
235
244
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import * as events from 'events';\n\n// Puppeteer Defaults\nimport * as Puppeteer from 'puppeteer';\n\nconst browserEvents = new events.EventEmitter();\n\nexport async function connect(options?: Puppeteer.ConnectOptions): Promise<Puppeteer.Browser> {\n const browser = await Puppeteer.connect(options || {});\n\n for (const plugin of plugins) {\n await plugin.init(browser);\n }\n\n const _close = browser.close;\n browser.close = async () => {\n await _close.apply(browser);\n browserEvents.emit('close');\n };\n\n return browser;\n}\n\n/** The method launches a browser instance with given arguments. The browser will be closed when the parent node.js process is closed. */\nexport async function launch(options?: Puppeteer.LaunchOptions & Puppeteer.BrowserLaunchArgumentOptions & Puppeteer.BrowserConnectOptions): Promise<Puppeteer.Browser> {\n const browser = await Puppeteer.launch({ defaultViewport: undefined, ...options });\n\n for (const plugin of plugins) {\n await plugin.init(browser);\n }\n\n const _close = browser.close;\n browser.close = async () => {\n await _close.apply(browser);\n browserEvents.emit('close');\n };\n\n return browser;\n}\n\n// PuppeteerPro\nlet interceptions = 0;\nexport class Plugin {\n protected browser: Puppeteer.Browser | null = null;\n private initialized = false;\n private startCounter = 0;\n protected dependencies: Plugin[] = [];\n protected requiresInterception = false;\n\n get isInitialized() { return this.initialized; }\n get isStopped() { return this.startCounter === 0; }\n\n protected async addDependency(plugin: Plugin) {\n this.dependencies.push(plugin);\n }\n\n async init(browser: Puppeteer.Browser) {\n if (this.initialized) return;\n\n this.browser = browser;\n\n const offOnClose: (() => void)[] = [];\n browserEvents.once('close', async () => {\n offOnClose.forEach(fn => fn());\n\n this.browser = null;\n this.initialized = false;\n this.startCounter = 0;\n\n await this.onClose();\n });\n\n this.startCounter++;\n\n const thisOnTargetCreated = this.onTargetCreated.bind(this);\n browser.on('targetcreated', thisOnTargetCreated);\n offOnClose.push(() => browser.off('targetcreated', thisOnTargetCreated));\n\n this.initialized = true;\n\n this.dependencies.forEach(x => x.init(browser));\n\n return this.afterLaunch(browser);\n }\n\n protected async afterLaunch(_browser: Puppeteer.Browser) { }\n protected async onClose() { }\n\n protected async onTargetCreated(target: Puppeteer.Target) {\n if (this.isStopped) return;\n\n if (target.type() !== 'page') return;\n const page = await target.page() as Puppeteer.Page;\n if (page.isClosed()) return;\n\n const offOnClose: (() => void)[] = [];\n page.once('close', async () => {\n offOnClose.forEach(fn => fn());\n });\n\n const requestHandlers: ((request: any) => void)[] = [];\n page.on('request', request => {\n const _respond = request.respond;\n let responded = 0;\n let respondArgs: IArguments;\n\n const _abort = request.abort;\n let aborted = 0;\n let abortArgs: IArguments;\n\n const _continue = request.continue;\n let continued = 0;\n let continueArgs: IArguments;\n\n // tslint:disable-next-line: only-arrow-functions\n const handleRequest = async function () {\n const total = responded + aborted + continued;\n\n if (!(request as any)._interceptionHandled) {\n if (responded === 1) await _respond.apply(request, respondArgs);\n else if (responded === 0 && aborted >= 1 && total === requestHandlers.length) await _abort.apply(request, abortArgs);\n else if (continued === requestHandlers.length) await _continue.apply(request, continueArgs);\n }\n };\n\n // tslint:disable-next-line: only-arrow-functions\n request.respond = async function () { responded++; respondArgs = respondArgs || arguments; await handleRequest(); };\n // tslint:disable-next-line: only-arrow-functions\n request.abort = async function () { aborted++; abortArgs = abortArgs || arguments; await handleRequest(); };\n // tslint:disable-next-line: only-arrow-functions\n request.continue = async function () { continued++; continueArgs = continueArgs || arguments; await handleRequest(); };\n\n requestHandlers.forEach(handler => handler(request));\n });\n\n const _pageOn = page.on;\n page.on = function async(eventName, handler) {\n if (eventName === 'request') {\n requestHandlers.push(handler);\n\n return page;\n } else {\n return _pageOn.call(page, eventName, handler);\n }\n };\n\n if (this.requiresInterception) {\n await page.setRequestInterception(true);\n\n const thisOnRequest = this.onRequest.bind(this);\n page.on('request', thisOnRequest);\n offOnClose.push(() => page.off('request', thisOnRequest));\n }\n\n const thisOnDialog = this.onDialog.bind(this);\n page.on('dialog', thisOnDialog);\n offOnClose.push(() => page.off('dialog', thisOnDialog));\n\n await this.onPageCreated(page);\n }\n protected async onPageCreated(_page: Puppeteer.Page) { }\n\n protected async onRequest(request: Puppeteer.HTTPRequest) {\n const interceptionHandled = (request as any)._interceptionHandled;\n if (interceptionHandled) return;\n if (this.isStopped) return request.continue();\n\n await this.processRequest(request);\n }\n protected async processRequest(_request: Puppeteer.HTTPRequest) { }\n\n protected async onDialog(dialog: Puppeteer.Dialog) {\n const handled = (dialog as any)._handled;\n\n if (handled) return;\n if (this.isStopped) return;\n\n await this.processDialog(dialog);\n }\n protected async processDialog(_dialog: Puppeteer.Dialog) { }\n\n protected async beforeRestart() { }\n async restart() {\n await this.beforeRestart();\n\n this.startCounter++;\n if (this.requiresInterception) interceptions++;\n\n this.dependencies.forEach(x => x.restart());\n\n await this.afterRestart();\n }\n protected async afterRestart() { }\n\n protected async beforeStop() { }\n async stop() {\n await this.beforeStop();\n\n this.startCounter--;\n if (this.requiresInterception) interceptions--;\n\n if (interceptions === 0 && this.browser) {\n const pages = await this.browser.pages();\n\n pages.filter(x => !x.isClosed()).forEach(async (page: Puppeteer.Page) => {\n await page.setRequestInterception(false);\n });\n }\n\n this.dependencies.forEach(x => x.stop());\n\n await this.afterStop();\n }\n protected async afterStop() { }\n\n protected async getFirstPage() {\n if (!this.browser) return null;\n\n const pages = await this.browser.pages();\n const openPages = pages.filter(x => !x.isClosed());\n const activePages = pages.filter(x => x.url() !== 'about:blank');\n\n return activePages[0] || openPages[0];\n }\n}\n\nlet plugins: Plugin[] = [];\nexport function addPlugin(plugin: Plugin) { plugins.push(plugin); }\nexport async function clearPlugins() {\n plugins.forEach(async plugin => {\n await plugin.stop();\n });\n\n plugins = [];\n}\n\nimport { AnonymizeUserAgentPlugin } from './plugins/anonymize.user.agent/index';\nexport function anonymizeUserAgent(): AnonymizeUserAgentPlugin {\n const plugin = new AnonymizeUserAgentPlugin();\n plugins.push(plugin);\n return plugin;\n}\n\nimport { AvoidDetectionPlugin } from './plugins/avoid.detection';\nexport function avoidDetection(): AvoidDetectionPlugin {\n const plugin = new AvoidDetectionPlugin();\n plugins.push(plugin);\n return plugin;\n}\n\nimport { BlockResourcesPlugin, Resource } from './plugins/block.resources';\nexport function blockResources(...resources: Resource[]): BlockResourcesPlugin {\n const plugin = new BlockResourcesPlugin(resources);\n plugins.push(plugin);\n return plugin;\n}\n\nimport { DisableDialogsPlugin } from './plugins/disable.dialogs';\nexport function disableDialogs(logMessages = false): DisableDialogsPlugin {\n const plugin = new DisableDialogsPlugin(logMessages);\n plugins.push(plugin);\n return plugin;\n}\n\nimport { ManageCookiesPlugin, ManageCookiesOption } from './plugins/manage.cookies';\nexport function manageCookies(opts: ManageCookiesOption): ManageCookiesPlugin {\n const plugin = new ManageCookiesPlugin(opts);\n plugins.push(plugin);\n return plugin;\n}"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import * as events from 'events';\n\n// Puppeteer Defaults\nimport * as Puppeteer from 'puppeteer';\n\nconst browserEvents = new events.EventEmitter();\n\nexport async function connect(options?: Puppeteer.ConnectOptions): Promise<Puppeteer.Browser> {\n const browser = await Puppeteer.connect(options || {});\n\n for (const plugin of plugins) {\n await plugin.init(browser);\n }\n\n const _close = browser.close;\n browser.close = async () => {\n await _close.apply(browser);\n browserEvents.emit('close');\n };\n\n return browser;\n}\n\n/** The method launches a browser instance with given arguments. The browser will be closed when the parent node.js process is closed. */\nexport async function launch(options?: Puppeteer.LaunchOptions & Puppeteer.BrowserLaunchArgumentOptions & Puppeteer.BrowserConnectOptions): Promise<Puppeteer.Browser> {\n if (!options) options = {};\n\n const browser = await Puppeteer.launch({ defaultViewport: undefined, ...options });\n\n for (const plugin of plugins) {\n await plugin.init(browser);\n }\n\n const _close = browser.close;\n browser.close = async () => {\n await _close.apply(browser);\n browserEvents.emit('close');\n };\n\n return browser;\n}\n\n// PuppeteerPro\nlet interceptions = 0;\nexport class Plugin {\n protected browser: Puppeteer.Browser | null = null;\n private initialized = false;\n private startCounter = 0;\n protected dependencies: Plugin[] = [];\n protected requiresInterception = false;\n\n get isInitialized() { return this.initialized; }\n get isStopped() { return this.startCounter === 0; }\n\n protected async addDependency(plugin: Plugin) {\n this.dependencies.push(plugin);\n }\n\n async init(browser: Puppeteer.Browser) {\n if (this.initialized) return;\n\n this.browser = browser;\n\n const offOnClose: (() => void)[] = [];\n browserEvents.once('close', async () => {\n offOnClose.forEach(fn => fn());\n\n this.browser = null;\n this.initialized = false;\n this.startCounter = 0;\n\n await this.onClose();\n });\n\n this.startCounter++;\n\n const thisOnTargetCreated = this.onTargetCreated.bind(this);\n browser.on('targetcreated', thisOnTargetCreated);\n offOnClose.push(() => browser.off('targetcreated', thisOnTargetCreated));\n\n this.initialized = true;\n\n this.dependencies.forEach(x => x.init(browser));\n\n return this.afterLaunch(browser);\n }\n\n protected async afterLaunch(_browser: Puppeteer.Browser) { }\n protected async onClose() { }\n\n protected async onTargetCreated(target: Puppeteer.Target) {\n if (this.isStopped) return;\n\n if (target.type() !== 'page') return;\n const page = await target.page() as Puppeteer.Page;\n if (page.isClosed()) return;\n\n const offOnClose: (() => void)[] = [];\n page.once('close', async () => {\n offOnClose.forEach(fn => fn());\n });\n\n const requestHandlers: ((request: any) => void)[] = [];\n page.on('request', request => {\n const _respond = request.respond;\n let responded = 0;\n let respondArgs: IArguments;\n\n const _abort = request.abort;\n let aborted = 0;\n let abortArgs: IArguments;\n\n const _continue = request.continue;\n let continued = 0;\n let continueArgs: IArguments;\n\n // tslint:disable-next-line: only-arrow-functions\n const handleRequest = async function () {\n const total = responded + aborted + continued;\n\n if (!(request as any)._interceptionHandled) {\n if (responded === 1) await _respond.apply(request, respondArgs);\n else if (responded === 0 && aborted >= 1 && total === requestHandlers.length) await _abort.apply(request, abortArgs);\n else if (continued === requestHandlers.length) await _continue.apply(request, continueArgs);\n }\n };\n\n // tslint:disable-next-line: only-arrow-functions\n request.respond = async function () { responded++; respondArgs = respondArgs || arguments; await handleRequest(); };\n // tslint:disable-next-line: only-arrow-functions\n request.abort = async function () { aborted++; abortArgs = abortArgs || arguments; await handleRequest(); };\n // tslint:disable-next-line: only-arrow-functions\n request.continue = async function () { continued++; continueArgs = continueArgs || arguments; await handleRequest(); };\n\n requestHandlers.forEach(handler => handler(request));\n });\n\n const _pageOn = page.on;\n page.on = function async(eventName, handler) {\n if (eventName === 'request') {\n requestHandlers.push(handler);\n\n return page;\n } else {\n return _pageOn.call(page, eventName, handler);\n }\n };\n\n if (this.requiresInterception) {\n await page.setRequestInterception(true);\n\n const thisOnRequest = this.onRequest.bind(this);\n page.on('request', thisOnRequest);\n offOnClose.push(() => page.off('request', thisOnRequest));\n }\n\n const thisOnDialog = this.onDialog.bind(this);\n page.on('dialog', thisOnDialog);\n offOnClose.push(() => page.off('dialog', thisOnDialog));\n\n await this.onPageCreated(page);\n }\n protected async onPageCreated(_page: Puppeteer.Page) { }\n\n protected async onRequest(request: Puppeteer.HTTPRequest) {\n const interceptionHandled = (request as any)._interceptionHandled;\n if (interceptionHandled) return;\n if (this.isStopped) return request.continue();\n\n await this.processRequest(request);\n }\n protected async processRequest(_request: Puppeteer.HTTPRequest) { }\n\n protected async onDialog(dialog: Puppeteer.Dialog) {\n const handled = (dialog as any)._handled;\n\n if (handled) return;\n if (this.isStopped) return;\n\n await this.processDialog(dialog);\n }\n protected async processDialog(_dialog: Puppeteer.Dialog) { }\n\n protected async beforeRestart() { }\n async restart() {\n await this.beforeRestart();\n\n this.startCounter++;\n if (this.requiresInterception) interceptions++;\n\n this.dependencies.forEach(x => x.restart());\n\n await this.afterRestart();\n }\n protected async afterRestart() { }\n\n protected async beforeStop() { }\n async stop() {\n await this.beforeStop();\n\n this.startCounter--;\n if (this.requiresInterception) interceptions--;\n\n if (interceptions === 0 && this.browser) {\n const pages = await this.browser.pages();\n\n pages.filter(x => !x.isClosed()).forEach(async (page: Puppeteer.Page) => {\n await page.setRequestInterception(false);\n });\n }\n\n this.dependencies.forEach(x => x.stop());\n\n await this.afterStop();\n }\n protected async afterStop() { }\n\n protected async getFirstPage() {\n if (!this.browser) return null;\n\n const pages = await this.browser.pages();\n const openPages = pages.filter(x => !x.isClosed());\n const activePages = pages.filter(x => x.url() !== 'about:blank');\n\n return activePages[0] || openPages[0];\n }\n}\n\nlet plugins: Plugin[] = [];\nexport function addPlugin(plugin: Plugin) { plugins.push(plugin); }\nexport async function clearPlugins() {\n plugins.forEach(async plugin => {\n await plugin.stop();\n });\n\n plugins = [];\n}\n\nimport { AnonymizeUserAgentPlugin } from './plugins/anonymize.user.agent/index';\nexport function anonymizeUserAgent(): AnonymizeUserAgentPlugin {\n const plugin = new AnonymizeUserAgentPlugin();\n plugins.push(plugin);\n return plugin;\n}\n\nimport { AvoidDetectionPlugin } from './plugins/avoid.detection';\nexport function avoidDetection(): AvoidDetectionPlugin {\n const plugin = new AvoidDetectionPlugin();\n plugins.push(plugin);\n return plugin;\n}\n\nimport { BlockResourcesPlugin, Resource } from './plugins/block.resources';\nexport function blockResources(...resources: Resource[]): BlockResourcesPlugin {\n const plugin = new BlockResourcesPlugin(resources);\n plugins.push(plugin);\n return plugin;\n}\n\nimport { DisableDialogsPlugin } from './plugins/disable.dialogs';\nexport function disableDialogs(logMessages = false): DisableDialogsPlugin {\n const plugin = new DisableDialogsPlugin(logMessages);\n plugins.push(plugin);\n return plugin;\n}\n\nimport { ManageCookiesPlugin, ManageCookiesOption } from './plugins/manage.cookies';\nexport function manageCookies(opts: ManageCookiesOption): ManageCookiesPlugin {\n const plugin = new ManageCookiesPlugin(opts);\n plugins.push(plugin);\n return plugin;\n}\n\nimport { SolveRecaptchaPlugin } from './plugins/solve.recaptcha';\nexport function solveRecaptchas(accessToken: string): SolveRecaptchaPlugin {\n const plugin = new SolveRecaptchaPlugin(accessToken);\n plugins.push(plugin);\n return plugin;\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "puppeteer-pro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "A simple puppeteer wrapper to enable useful plugins with ease",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,15 +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.906"
|
|
41
|
+
},
|
|
37
42
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^17.0.10",
|
|
44
|
+
"@types/user-agents": "^1.0.2",
|
|
39
45
|
"chai": "^4.3.4",
|
|
40
|
-
"copyfiles": "^2.
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
46
|
+
"copyfiles": "^2.4.1",
|
|
47
|
+
"dotenv-safe": "^8.2.0",
|
|
48
|
+
"eslint": "^8.7.0",
|
|
49
|
+
"mocha": "^9.2.0",
|
|
50
|
+
"puppeteer": "^13.1.1",
|
|
44
51
|
"rimraf": "^3.0.2",
|
|
45
|
-
"tslint": "^6.1.
|
|
46
|
-
"typescript": "^4.
|
|
52
|
+
"tslint": "^6.1.3",
|
|
53
|
+
"typescript": "^4.5.5"
|
|
47
54
|
}
|
|
48
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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/avoid.detection/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAK3E,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,YAAY,6BAAoC;cAEhC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/avoid.detection/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAK3E,qBAAa,oBAAqB,SAAQ,MAAM;IAC9C,YAAY,6BAAoC;cAEhC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;CAKnD"}
|
|
@@ -12,11 +12,8 @@ class AvoidDetectionPlugin extends index_1.Plugin {
|
|
|
12
12
|
this.dependencies = [new index_2.AnonymizeUserAgentPlugin()];
|
|
13
13
|
}
|
|
14
14
|
async onPageCreated(page) {
|
|
15
|
-
if (!page._pageBindings.has('isStopped')) {
|
|
16
|
-
await page.exposeFunction('isStopped', () => this.isStopped);
|
|
17
|
-
}
|
|
18
15
|
for (const injection of injections) {
|
|
19
|
-
if (!page.isClosed())
|
|
16
|
+
if (!this.isStopped && !page.isClosed())
|
|
20
17
|
await page.evaluateOnNewDocument(injection);
|
|
21
18
|
}
|
|
22
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/avoid.detection/index.ts"],"names":[],"mappings":";;AAAA,yBAAyB;AACzB,6BAA6B;AAG7B,uCAAqC;AACrC,2DAA2E;AAE3E,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,aAAa,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,gBAAgB,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;AAEhH,MAAa,oBAAqB,SAAQ,cAAM;IAAhD;;QACE,iBAAY,GAAG,CAAC,IAAI,gCAAwB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/avoid.detection/index.ts"],"names":[],"mappings":";;AAAA,yBAAyB;AACzB,6BAA6B;AAG7B,uCAAqC;AACrC,2DAA2E;AAE3E,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,aAAa,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,EAAE,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,gBAAgB,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;AAEhH,MAAa,oBAAqB,SAAQ,cAAM;IAAhD;;QACE,iBAAY,GAAG,CAAC,IAAI,gCAAwB,EAAE,CAAC,CAAC;IAOlD,CAAC;IALW,KAAK,CAAC,aAAa,CAAC,IAAoB;QAChD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;YAClC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;gBAAE,MAAM,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;SACtF;IACH,CAAC;CACF;AARD,oDAQC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as Puppeteer from 'puppeteer';\n\nimport { Plugin } from '../../index';\nimport { AnonymizeUserAgentPlugin } from './../anonymize.user.agent/index';\n\nconst injectionsFolder = path.resolve(`${__dirname}/injections`);\nconst injections = fs.readdirSync(injectionsFolder).map(fileName => require(`${injectionsFolder}/${fileName}`));\n\nexport class AvoidDetectionPlugin extends Plugin {\n dependencies = [new AnonymizeUserAgentPlugin()];\n\n protected async onPageCreated(page: Puppeteer.Page) {\n for (const injection of injections) {\n if (!this.isStopped && !page.isClosed()) await page.evaluateOnNewDocument(injection);\n }\n }\n}"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as Puppeteer from 'puppeteer';
|
|
2
|
+
import { Plugin } from '../../index';
|
|
3
|
+
import { AvoidDetectionPlugin } from './../avoid.detection/index';
|
|
4
|
+
export declare class SolveRecaptchaPlugin extends Plugin {
|
|
5
|
+
dependencies: AvoidDetectionPlugin[];
|
|
6
|
+
witAiAccessToken?: string;
|
|
7
|
+
constructor(witAiAccessToken: string);
|
|
8
|
+
hasCaptcha(page: Puppeteer.Page): Promise<boolean>;
|
|
9
|
+
solveRecaptcha(page: Puppeteer.Page): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;IAK9B,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;IAI/B,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI;CAgE1C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
|
+
exports.SolveRecaptchaPlugin = void 0;
|
|
3
|
+
const axios_1 = require("axios");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const ghost_cursor_1 = require("ghost-cursor");
|
|
6
|
+
const index_1 = require("../../index");
|
|
7
|
+
const index_2 = require("./../avoid.detection/index");
|
|
8
|
+
const injection = require(path.resolve(`${__dirname}/injections`) + '/utils.js'); // tslint:disable-line: no-var-requires
|
|
9
|
+
const randomBetween = (min, max) => Math.floor(Math.random() * (max - min)) + min;
|
|
10
|
+
class SolveRecaptchaPlugin extends index_1.Plugin {
|
|
11
|
+
constructor(witAiAccessToken) {
|
|
12
|
+
super();
|
|
13
|
+
this.dependencies = [new index_2.AvoidDetectionPlugin()];
|
|
14
|
+
this.witAiAccessToken = witAiAccessToken;
|
|
15
|
+
}
|
|
16
|
+
async hasCaptcha(page) {
|
|
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')); });
|
|
18
|
+
}
|
|
19
|
+
async solveRecaptcha(page) {
|
|
20
|
+
var _a;
|
|
21
|
+
if (this.isStopped)
|
|
22
|
+
return;
|
|
23
|
+
if (!this.witAiAccessToken)
|
|
24
|
+
return;
|
|
25
|
+
if (!(await this.hasCaptcha(page)))
|
|
26
|
+
return;
|
|
27
|
+
const cursor = (0, ghost_cursor_1.createCursor)(page);
|
|
28
|
+
async function waitForSelector(iframeUrlIncludes, selector) {
|
|
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);
|
|
30
|
+
}
|
|
31
|
+
async function findAndClick(iframeUrlIncludes, selector) {
|
|
32
|
+
var _a;
|
|
33
|
+
await waitForSelector(iframeUrlIncludes, selector);
|
|
34
|
+
const element = await ((_a = page.frames().find(frame => frame.url().includes(iframeUrlIncludes))) === null || _a === void 0 ? void 0 : _a.$(selector));
|
|
35
|
+
if (!element)
|
|
36
|
+
return;
|
|
37
|
+
await sleep(randomBetween(1 * 1000, 3 * 1000));
|
|
38
|
+
await cursor.click(element);
|
|
39
|
+
}
|
|
40
|
+
let numTriesLeft = 5;
|
|
41
|
+
async function isFinished() {
|
|
42
|
+
if (--numTriesLeft === 0)
|
|
43
|
+
return true;
|
|
44
|
+
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-checkbox-checked')); });
|
|
45
|
+
}
|
|
46
|
+
await findAndClick('api2/anchor', '#recaptcha-anchor');
|
|
47
|
+
await findAndClick('api2/bframe', '.rc-button-audio');
|
|
48
|
+
while (!(await isFinished())) {
|
|
49
|
+
await waitForSelector('api2/bframe', '.rc-audiochallenge-tdownload-link');
|
|
50
|
+
const audioUrl = await page.evaluate(async () => {
|
|
51
|
+
var _a, _b, _c;
|
|
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;
|
|
53
|
+
});
|
|
54
|
+
if (!audioUrl)
|
|
55
|
+
return;
|
|
56
|
+
const audioArray = await page.evaluate(injection, audioUrl);
|
|
57
|
+
if (!audioArray)
|
|
58
|
+
return;
|
|
59
|
+
const audioBuffer = Buffer.from(new Int8Array(audioArray));
|
|
60
|
+
const response = await axios_1.default.post('https://api.wit.ai/speech?v=20210701', audioBuffer, {
|
|
61
|
+
headers: {
|
|
62
|
+
'Authorization': `Bearer ${this.witAiAccessToken}`,
|
|
63
|
+
'Content-Type': 'audio/wav'
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
if (response.data.text) {
|
|
67
|
+
const responseInput = await ((_a = page.frames().find(frame => frame.url().includes('api2/bframe'))) === null || _a === void 0 ? void 0 : _a.$('#audio-response'));
|
|
68
|
+
responseInput === null || responseInput === void 0 ? void 0 : responseInput.type(response.data.text);
|
|
69
|
+
await findAndClick('api2/bframe', '#recaptcha-verify-button');
|
|
70
|
+
await sleep(1000);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
await findAndClick('api2/bframe', '#recaptcha-reload-button');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.SolveRecaptchaPlugin = SolveRecaptchaPlugin;
|
|
79
|
+
function sleep(timeout) {
|
|
80
|
+
return new Promise(resolve => setTimeout(resolve, timeout));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/solve.recaptcha/index.ts"],"names":[],"mappings":"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","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}"]}
|
|
@@ -0,0 +1,145 @@
|
|
|
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);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return buffer;
|
|
98
|
+
},
|
|
99
|
+
interleave: (inputL, inputR) => {
|
|
100
|
+
var length = inputL.length + inputR.length;
|
|
101
|
+
var result = new Float32Array(length);
|
|
102
|
+
|
|
103
|
+
var index = 0;
|
|
104
|
+
var inputIndex = 0;
|
|
105
|
+
|
|
106
|
+
while (index < length) {
|
|
107
|
+
result[index++] = inputL[inputIndex];
|
|
108
|
+
result[index++] = inputR[inputIndex];
|
|
109
|
+
inputIndex++;
|
|
110
|
+
}
|
|
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));
|
|
127
|
+
}
|
|
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)];
|
|
145
|
+
};
|