resolve captcha

This commit is contained in:
spiduler
2020-10-10 01:06:58 +09:00
parent f20c02dadc
commit 669e761bcb
2 changed files with 83 additions and 10 deletions

View File

@@ -15,6 +15,7 @@
"express-logging": "^1.1.1", "express-logging": "^1.1.1",
"http-status-codes": "^1.4.0", "http-status-codes": "^1.4.0",
"logops": "^2.1.1", "logops": "^2.1.1",
"node-fetch": "^2.6.1",
"puppeteer-cluster": "^0.22.0", "puppeteer-cluster": "^0.22.0",
"puppeteer-core": "^1.9.0", "puppeteer-core": "^1.9.0",
"selenium-webdriver": "^4.0.0-alpha.7" "selenium-webdriver": "^4.0.0-alpha.7"

View File

@@ -1,6 +1,8 @@
const logger = require("logops") const logger = require("logops")
, config = require('../../config') , config = require('../../config')
, { Builder, Capabilities, By, Key, until } = require('selenium-webdriver') , { Builder, Capabilities, By, Key, until } = require('selenium-webdriver')
, url = require('url')
, fetch = require('node-fetch')
, { Options } = require('selenium-webdriver/chrome'); , { Options } = require('selenium-webdriver/chrome');
class SeleniumBrowser { class SeleniumBrowser {
@@ -9,6 +11,8 @@ class SeleniumBrowser {
this.driver = null this.driver = null
this.config = { useHub: true, browser: 'chrome' } this.config = { useHub: true, browser: 'chrome' }
this.capabilities = Capabilities.chrome() this.capabilities = Capabilities.chrome()
this.sleep = m => new Promise(r => setTimeout(r, m))
this.isRecaptchaReseponseEmpty = false
} }
async setDriver() { async setDriver() {
@@ -34,19 +38,87 @@ class SeleniumBrowser {
opts.addArguments(this.getChromeArgs()) opts.addArguments(this.getChromeArgs())
// opts.setChromeBinaryPath('/usr/bin/chromedriver') // opts.setChromeBinaryPath('/usr/bin/chromedriver')
return new Builder().forBrowser(this.config.browser).setChromeOptions(opts).build(); return new Builder().forBrowser(this.config.browser).setChromeOptions(opts).build();
// let driver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(this.getChromeArgs()).build(); // let driver = new
// webdriver.Builder().forBrowser('chrome').setChromeOptions(this.getChromeArgs()).build();
} }
async request(uri) { async request(uri) {
logger.info('Request URL %s', this.website + uri) if (this.isRecaptchaReseponseEmpty) {
return this.driver.get(this.website + uri).then(d => this.driver.findElement(By.css('body')).getAttribute('innerHTML')) return ''
// .then(html => { } else {
// // solve the captcha with API logger.info('Request URL %s', this.website + uri)
// const token = await solveCaptcha(params, api) return this.driver.get(this.website + uri).then(d => this.driver.findElement(By.css('body')).getAttribute('innerHTML'))
// }) .then(html => this.getHtml(html))
// return await driver.findElement(By.css('body')).getAttribute('innerHTML') // return await
//.sendKeys('webdriver', Key.RETURN); // driver.findElement(By.css('body')).getAttribute('innerHTML')
// await driver.wait(until.titleIs('webdriver - www.real.de'), 1000); // .sendKeys('webdriver', Key.RETURN);
/// await driver.wait(until.titleIs('webdriver - www.real.de'), 1000);
}
}
async getHtml(html) {
// return html
// check if it's forbbidden page
if (html.indexOf('grecaptcha') > -1 || html.indexOf('www.google.com/recaptcha/api2/anchor') > -1) {
this.isRecaptchaReseponseEmpty = true
let iframeSrc = await this.driver.findElement(By.css('#grecaptcha iframe')).getAttribute('src')
let captcha2Params = {
"key": "62fc5ef52fd4befe266d224796a7ea6f",
"method": "userrecaptcha",
"googlekey": url.parse(iframeSrc, true).query.k,
"pageurl": await this.driver.getCurrentUrl(),
"json": 1
}
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.info('2captcha IN-request response : %j', res)
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 }
do {
res = await this.requestCaptchaResult(res, requestId)
} while (res.request == 'CAPCHA_NOT_READY')
return res
}).then(res => {
logger.info('2captcha solved : %j', res)
// this.driver.findElement(By.css('#g-recaptcha-response')).setAttribute('innerHTML', res.request)
this.driver.executeScript('captchaCallback("' + res.request + '")')
this.driver.wait(10000).then(d => {
this.driver.findElement(By.css('#g-recaptcha-response')).then(function (webElement) {
logger.error(res, 'Failed to overcome recaptcha')
}, function (err) {
// if (err.state && err.state === 'no such element') {
// console.log('Element not found');
// } else {
// webdriver.promise.rejected(err);
// }
logger.info('Success to overcome recaptcha')
this.isRecaptchaReseponseEmpty = false
})
})
}).catch(error => {
logger.error({ message: error.message }, 'Error occured while process with 2captcha')
})
return ''
} else {
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())
}
logger.info('Request 2captcha solving result after 20 senconds')
await this.sleep(1000 * 20)
return fetch(requestUrl).then(res => res.json())
} }
async close() { async close() {