This commit is contained in:
spiduler
2020-10-20 08:12:48 +09:00
parent 645ea995d6
commit 7de1f460f0
3 changed files with 35 additions and 63 deletions

View File

@@ -63,22 +63,12 @@ process.on('SIGTERM', exitHandler.bind(null, { cleanup: true }));
* request handler * request handler
*/ */
app.post('/', async (req, res, next) => { app.post('/', async (req, res, next) => {
const requestPage = () => browser.get(req.body.uri, req.body.waitElement).then(html => res.send(html)).catch(e => { browser.get(req.body).then(html => res.send(html)).catch(e => {
if(e instanceof NoSuchSessionError) { if(e instanceof NoSuchSessionError) {
browser.reset()
logger.error({ reason: e.message, url: req.url }, 'Browser session expired') logger.error({ reason: e.message, url: req.url }, 'Browser session expired')
}else { }else {
logger.error({ reason: e.message, url: req.url }, 'Browser error occured') logger.error({ reason: e.message, url: req.url }, 'Browser error occured')
} }
res.status(500).send({ code: 500, message: e.message }) res.status(500).send({ code: 500, message: e.message })
// browser.close().then(() => e instanceof puppeteerErrors.TimeoutError ? setTimeout(() => requestPage(), 3000) : res.status(500).send(e.message))
}) })
requestPage()
})
app.get('/restart', (req, res, next) => {
// browser.close().then(() => {
// res.json({message: 'Browser closed and lanuch with new request'})
// })
process.exit()
}) })

View File

@@ -7,56 +7,46 @@ const logger = require("logops")
class SeleniumBrowser { class SeleniumBrowser {
constructor() { constructor() {
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.sleep = m => new Promise(r => setTimeout(r, m))
this.isRecaptchaReseponseEmpty = false this.isRecaptchaReseponseEmpty = false
} }
async setDriver() { getDriver() {
if (this.config.useHub) { let opts = new Options;
let opts = new Options;
opts.addArguments(this.getChromeArgs())
this.driver = await new Builder()
.usingServer('http://spiduler-chrome:4444/wd/hub')
.withCapabilities(this.capabilities)
.forBrowser(this.config.browser)
.setChromeOptions(opts)
.build();
} else {
this.driver = await this.setLocalDriver()
}
}
setLocalDriver() {
let opts = new Options
opts.addArguments(this.getChromeArgs()) opts.addArguments(this.getChromeArgs())
return new Builder().forBrowser(this.config.browser).setChromeOptions(opts).build(); return new Builder()
.usingServer('http://spiduler-chrome:4444/wd/hub')
.withCapabilities(this.capabilities)
.forBrowser(this.config.browser)
.setChromeOptions(opts)
.build();
} }
request(uri, waitElement) { request(params) {
let uri = params.uri
let waitElement = params.waitElement
if (this.isRecaptchaReseponseEmpty) { if (this.isRecaptchaReseponseEmpty) {
return '' return ''
} else { } else {
logger.info('URL %s', uri) logger.info('URL %s', uri)
if (uri.indexOf('://') > 3) { if (uri.indexOf('://') > 3) {
return this.driver.get(uri) return this.getDriver().then(driver => {
// .then(() => { return driver.get(uri)
// if (waitElement) { .then(() => {
// return this.driver.wait(until.elementIsVisible(this.driver.findElement(By.css(waitElement))), 5 * 1000) if (waitElement) {
// } return driver.wait(until.elementIsVisible(driver.findElement(By.css(waitElement))), 5 * 1000)
// return true }
// }) return true
.then(() => this.driver.findElement(By.css('body'))) })
.then(body => body.getAttribute('innerHTML')) .then(() => driver.findElement(By.css('body')))
.then(html => this.getHtml(html)) .then(body => body.getAttribute('innerHTML'))
// .catch(error => { .then(html => this.getHtml(html))
// logger.error({ message: error.message }, 'No image element') .finally(() => {
// return this.driver.findElement(By.css('body')) driver.quit()
// .then(body => body.getAttribute('innerHTML')) })
// .then(html => this.getHtml(html)) })
// })
} else { } else {
logger.info('URL %s is not valid', uri) logger.info('URL %s is not valid', uri)
return '' return ''
@@ -95,17 +85,11 @@ class SeleniumBrowser {
return res return res
}).then(res => { }).then(res => {
logger.debug(res, '2captcha solved') logger.debug(res, '2captcha solved')
// this.driver.findElement(By.css('#g-recaptcha-response')).setAttribute('innerHTML', res.request)
this.driver.executeScript('captchaCallback("' + res.request + '")') this.driver.executeScript('captchaCallback("' + res.request + '")')
this.driver.wait(10000).then(d => { this.driver.wait(10000).then(d => {
this.driver.findElement(By.css('#g-recaptcha-response')).then(function (webElement) { this.driver.findElement(By.css('#g-recaptcha-response')).then(function (webElement) {
logger.error(res, 'Failed to overcome recaptcha') logger.error(res, 'Failed to overcome recaptcha')
}, function (err) { }, 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') logger.info('Success to overcome recaptcha')
}) })
}) })
@@ -131,7 +115,9 @@ class SeleniumBrowser {
} }
async close() { async close() {
this.pool.drain().then(function () {
this.pool.clear();
});
} }
getChromeArgs() { getChromeArgs() {
@@ -152,5 +138,4 @@ class SeleniumBrowser {
} }
const browser = new SeleniumBrowser const browser = new SeleniumBrowser
browser.setDriver()
module.exports = browser module.exports = browser

View File

@@ -8,17 +8,14 @@ class HeadlessService {
} }
get(uri, waitElement) { get(params) {
return browser.request(uri, waitElement) return browser.request(params)
} }
close() { close() {
return browser.close() return browser.close()
} }
reset() {
browser.setDriver()
}
} }
module.exports = new HeadlessService module.exports = new HeadlessService