This commit is contained in:
spiduler
2020-10-22 12:34:01 +09:00
parent 478492187e
commit 31f01f0dfa

View File

@@ -14,7 +14,6 @@ class SeleniumBrowser {
}
this.capabilities = Capabilities.chrome()
this.sleep = m => new Promise(r => setTimeout(r, m))
this.isRecaptchaReseponseEmpty = false
this.pool = pool.createPool({
create: () => {
return this.getDriver();
@@ -40,102 +39,83 @@ class SeleniumBrowser {
async request(params) {
let uri = params.uri
if (this.isRecaptchaReseponseEmpty) {
throw new Error('2captcha still processing')
} else {
logger.info('URL %s', uri)
if (uri.indexOf('://') > 3) {
return this.pool.acquire().then(driver => {
return driver.get(uri)
return this.pool.acquire().then(async driver => {
let html = await driver.get(uri)
.then(() => driver.findElement(By.css('body')))
.then(body => body.getAttribute('innerHTML'))
.then(html => this.getHtml(driver, html, params))
let htmlPromise = this.isCaptchaPage(html) ? this.resolveCaptcha(driver) : this.getHtml(driver, html, params)
html = await htmlPromise
this.pool.release(driver)
return html
})
} else {
throw new Error('Invalid URI - ' + uri)
}
}
isCaptchaPage(html) {
return html.indexOf('grecaptcha') > -1 || html.indexOf('www.google.com/recaptcha/api2/anchor') > -1
}
async getHtml(driver, html, params) {
if (html.indexOf('grecaptcha') > -1 || html.indexOf('www.google.com/recaptcha/api2/anchor') > -1) {
this.isRecaptchaReseponseEmpty = true
setTimeout(() => {
this.isRecaptchaReseponseEmpty = false
}, 1000 * 60)
let iframeSrc = await driver.findElement(By.css('#grecaptcha iframe')).getAttribute('src')
let captcha2Params = {
"key": "62fc5ef52fd4befe266d224796a7ea6f",
"method": "userrecaptcha",
"googlekey": url.parse(iframeSrc, true).query.k,
"pageurl": await driver.getCurrentUrl(),
"json": 1
getCaptchaRequestUri(id) {
return 'https://2captcha.com/res.php?key=62fc5ef52fd4befe266d224796a7ea6f&json=1&action=get&id=' + id
}
let requestUrl = new url.URL('https://2captcha.com/in.php')
requestUrl.search = new url.URLSearchParams(captcha2Params).toString();
fetch(requestUrl).then(res => res.json()).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))
}
return res.request
}).then(async requestId => {
let res = { request: null }
let maxRetry = 10
do {
maxRetry = maxRetry - 1
res = await this.requestCaptchaResult(res, requestId)
if (maxRetry == 0) break
} while (res.request == 'CAPCHA_NOT_READY')
this.isRecaptchaReseponseEmpty = false
return res
}).then(res => {
driver.executeScript('captchaCallback("' + res.request + '")')
driver.wait(10000).then(d => {
driver.findElement(By.css('#g-recaptcha-response'))
.then(() => {
throw new Error('Still captcha page')
}).catch(err => {
logger.error({ message: err.message }, 'Since 2captcha solved')
this.pool.release(driver)
})
})
}).catch(error => {
logger.error({ message: error.message }, 'Error occured while process with 2captcha')
this.pool.release(driver)
})
throw new Error('2captcha processing')
} else {
getHtml(driver, html, params) {
if (params.waitElement) {
return driver.get(params.uri)
.then(() => driver.wait(until.elementLocated(By.css(params.waitElement))))
.then(() => driver.findElement(By.css('body')))
.then(body => body.getAttribute('innerHTML'))
.then(html => {
this.pool.release(driver)
return html
}).catch(err => {
logger.error({ message: err.message }, 'Wait element failed')
this.pool.release(driver)
throw new Error('2captcha processing')
})
} else {
this.pool.release(driver)
return html
}
}
}
async requestCaptchaResult(res, requestId) {
let requestUrl = 'https://2captcha.com/res.php?key=62fc5ef52fd4befe266d224796a7ea6f&json=1&action=get&id=' + requestId
if (res.request == 'CAPCHA_NOT_READY') {
logger.info('2captcha still working so request solving result after 5 senconds')
await this.sleep(1000 * 5)
return fetch(requestUrl).then(res => res.json())
resolveCaptcha(driver) {
return driver.findElement(By.css('#grecaptcha iframe')).getAttribute('src')
.then(async src => {
return {
"key": "62fc5ef52fd4befe266d224796a7ea6f",
"method": "userrecaptcha",
"googlekey": url.parse(src, true).query.k,
"pageurl": await driver.getCurrentUrl(),
"json": 1
}
})
.then(params => {
let requestUrl = new url.URL('https://2captcha.com/in.php')
requestUrl.search = new url.URLSearchParams(params).toString();
return fetch(requestUrl).then(res => res.json()).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))
}
return res.request
})
})
.then(async id => {
logger.info('Request 2captcha solving result after 20 senconds')
await this.sleep(1000 * 20)
return fetch(requestUrl).then(res => res.json())
let res = await fetch(this.getCaptchaRequestUri(id)).then(res => res.json())
let maxRetry = 10
while (res.request == 'CAPCHA_NOT_READY') {
await this.sleep(1000 * 5)
maxRetry = maxRetry - 1
logger.info('2captcha still working so request solving result after 5 senconds')
res = await fetch(this.getCaptchaRequestUri(id)).then(res => res.json())
if (maxRetry == 0) break
}
return res
})
.then(res => {
return driver.executeScript('captchaCallback("' + res.request + '")').then(async () => await this.sleep(1000 * 5))
})
}
async close() {