diff --git a/src/component/CaptchaComp.js b/src/component/CaptchaComp.js index 2619049..8bd383c 100644 --- a/src/component/CaptchaComp.js +++ b/src/component/CaptchaComp.js @@ -2,6 +2,7 @@ const logger = require("logops") , { By } = require('selenium-webdriver') , url = require('url') , fetch = require('node-fetch') +const { request } = require("./SeleniumBrowser") class CaptchaComp { @@ -41,21 +42,30 @@ class CaptchaComp { o.search = new url.URLSearchParams(params).toString(); return o } - let params = Object.assign(this.params.in, { googlekey: params.googlekey, pageurl: params.pageurl }) + params = Object.assign(this.params.in, { googlekey: params.googlekey, pageurl: params.pageurl }) let o = new url.URL(this.api.in) o.search = new url.URLSearchParams(params).toString(); return o } - resolveCaptcha(driver) { + getParams(params) { + return Object.assign({ + method: 'GET', + headers: { "Content-Type": "application/json" }, + timeout: this.api.retryTimeout + }, params) + } + + request(params) { + return fetch(this.getUrl(params), this.getParams()).then(res => res.json()) + } + + requestResolve(driver) { return driver.findElement(By.css('#grecaptcha iframe')).getAttribute('src') .then(src => url.parse(src, true).query.k) .then(googlekey => { return driver.getCurrentUrl().then(pageurl => { - return fetch(this.getUrl({ googlekey: googlekey, pageurl: pageurl }), { - method: 'GET', - headers: { "Content-Type": "application/json" } - }).then(res => res.json()).then(res => { + return this.request({ googlekey: googlekey, pageurl: pageurl }).then(res => { logger.debug(res, '2captcha IN-request response') if (!res.hasOwnProperty('request')) { throw new Error('2captcha IN-request response has no data request id : ' + JSON.stringify(res)) @@ -63,21 +73,28 @@ class CaptchaComp { return res.request }) }) + }).then(id => { + logger.info({ id: this.api.id }, 'Request answer delay for 20 senconds') + return new Promise(r => setTimeout(() => r(id), 20000)) }) - .then(async id => { - logger.info('Request 2captcha solving result after 20 senconds') - await this.sleep(1000 * 20) - let res = await fetch(this.getUrl({ id: id })).then(res => res.json()) - let maxRetry = 10 - while (res.request == 'CAPCHA_NOT_READY') { - await this.sleep(this.api.retryTimeout) - maxRetry = maxRetry - 1 - logger.info('2captcha still working so request solving result after 5 senconds') - res = await fetch(this.getUrl({ id: id })).then(res => res.json()) - if (maxRetry == 0) break - } - return res - }) + } + + async getAnswer(res) { + let retryLimit = 10 + while (res.request == 'CAPCHA_NOT_READY') { + await this.sleep(this.api.retryTimeout) + retryLimit = retryLimit - 1 + logger.info('Retry get recap answer in 5 senconds') + res = await this.request({ id: id }) + if (retryLimit == 0) break + } + return res + } + + resolveCaptcha(driver) { + return this.requestResolve(driver) + .then(id => this.request({ id: id })) + .then(res => this.getAnswer(res)) .then(res => { return driver.executeScript('captchaCallback("' + res.request + '")').then(() => this.sleep(1000 * 5)) }) diff --git a/src/component/SeleniumBrowser.js b/src/component/SeleniumBrowser.js index 79c1d1a..7504c42 100644 --- a/src/component/SeleniumBrowser.js +++ b/src/component/SeleniumBrowser.js @@ -21,7 +21,7 @@ class SeleniumBrowser { .then(body => body.getAttribute('innerHTML')) let htmlPromise = captcha.isCaptchaPage(html) ? captcha.resolveCaptcha(driver) : this.getHtml(driver, html, params) html = await htmlPromise - this.pool.release(driver) + if (this.pool.isBorrowedResource(driver)) this.pool.release(driver) return html }) } else { @@ -38,6 +38,10 @@ class SeleniumBrowser { .then(html => { return html }) + .catch(err => { + logger.error({ message: err.message }, 'Get html failed') + this.pool.release(driver) + }) } else { return html }