Skip to content

Commit

Permalink
Merge pull request #6 from viniciusgava/fix/integration-fix-2020-11
Browse files Browse the repository at this point in the history
Fix integration with the new statement screen
  • Loading branch information
viniciusgava committed Oct 30, 2020
2 parents b036baf + 082514c commit a35dfc6
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 215 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
# Itau Scraper
Download Itaú exportable files using node and Puppeteer.
Available file formats:
- PDF
- XLS
- TXT - It's a CSV with semi-colon
- OFX - Money 2000 *(DEFAULT)*
- OFC 1.0 - Money 1995 a Money 1999
- OFC 1.06 - Quicken 6
- OFX - Money 2000 *(DEFAULT)*
- TXT - It's a CSV with semi-colon

## Usage
```bash
node run.js --branch=0000 --account=00000-0 --password=000000 --days 5
```

## Usage - Docker
### WARNING: Docker image is outdated
```bash
docker run -v $(pwd):/usr/itauscrapper/download \
-e BRANCH='0000' \
Expand All @@ -33,9 +36,10 @@ Options:
--branch, -b Itaú branch number, format: 0000 [string] [required]
--account, -c Itaú account number, format: 00000-0 [string] [required]
--password, -p Itaú account digital password(6 digits) [number] [required]
--days, -d Transaction log days [number] [required]
--days, -d Transaction log days
[number] [required] [choices: 3, 5, 7, 15, 30, 60, 90]
--file_format, -f File format to export
[choices: "ofc1", "ofc106", "ofx", "txt"] [default: "ofx"]
[choices: "pdf", "xls", "txt", "ofx", "ofc10", "ofc106"] [default: "ofx"]
--node_env Node environment
[choices: "development", "production", "docker"] [default: "production"]
```
Expand Down
2 changes: 1 addition & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
},
"download": {
"path": "./download",
"filename": "ITAU_${searchDate.year}-${searchDate.month}-${searchDate.day}_${options.days}_days_before_${searchDate.timestamp}"
"filename": "ITAU_${days}_days_before_${timestamp}"
}
}
88 changes: 52 additions & 36 deletions itauscraper.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,49 +41,61 @@ const stepExport = async (page, options) => {
// Go to extrato page
await page.evaluate(() => { document.querySelector('.sub-mnu').style.display = 'block' })
await page.waitFor(1000)
await page.hover('#varejo > header > div > nav > ul > li > div > div > div:nth-child(1) > ul:nth-child(1) > li:nth-child(3) > a')
await page.click('#varejo > header > div > nav > ul > li > div > div > div:nth-child(1) > ul:nth-child(1) > li:nth-child(3) > a')
await page.waitForNavigation()

await page.hover('#varejo > header > div.container > nav > ul > li > div > div > div:nth-child(1) > ul:nth-child(1) > li:nth-child(2) > a')
await page.click('#varejo > header > div.container > nav > ul > li > div > div > div:nth-child(1) > ul:nth-child(1) > li:nth-child(2) > a')
console.log('Statement page loaded.')

// Select frame
const frame = page.frames().find(frame => frame.name() === 'CORPO')

// Go to export page
await frame.waitFor('a[title="Salvar em outros formatos"]')
console.log('Opening export page...')
await frame.click('a[title="Salvar em outros formatos"]')
await frame.waitForNavigation()
console.log('Export page loaded.')

let searchDate = moment().subtract(options.days, 'days')
searchDate = {
year: searchDate.format('YYYY'),
month: searchDate.format('MM'),
day: searchDate.format('DD'),
timestamp: moment().unix()
}
// Close guide
await stepCloseStatementGuide(page)
console.log('Statement has been closed')

// Close menu
await page.evaluate(() => { document.querySelector('.sub-mnu').style.display = 'none' })
await page.waitFor(1000)
console.log('Menu has been closed')

// Select transactions tab
await page.click('#btn-aba-lancamentos')
console.log('Selected transactions tab')

// Select all entries on the filters
await page.click('#extrato-filtro-lancamentos .todas-filtro-extrato-pf')
console.log('Selected all entries on the filters')

// Select period of days
await page.select('cpv-select[model=\'pc.periodoSelecionado\'] select', options.days.toString())
console.log('Selected period of days on the filters')

// wait load transactions
await page.waitFor(10000)

console.log('Filling export date period..: ', searchDate)
// Fill export fields
await frame.waitFor('#TRNcontainer01')
await frame.type('#Dia', searchDate.day)
await frame.type('#Mes', searchDate.month)
await frame.type('#Ano', searchDate.year)
console.log('Selecting export document type..: ' + options.file_format)
await frame.click(getFileFormatSelector(options))
// configure Download Trigger
let triggerDownload = (fileFormat) => { exportarExtratoArquivo('formExportarExtrato', fileFormat) }// eslint-disable-line
if (options.file_format === 'pdf') {
triggerDownload = (fileFormat) => { exportarArquivoLancamentoImprimirPdf('pdf') } // eslint-disable-line
}

const finalFilePath = path.resolve(
options.download.path,
eval('`' + options.download.filename + '`') // eslint-disable-line
options.download.filename.interpolate({
days: options.days,
timestamp: moment().unix()
})
)

console.log('Starting download...')
const finalFilePathWithExtension = await download(frame, 'img[alt="Continuar"]', finalFilePath)
const finalFilePathWithExtension = download(page, triggerDownload, finalFilePath, options)
console.log('Download has been finished.')
console.log('Export document final path: ', finalFilePathWithExtension)
}

const stepCloseStatementGuide = async (page) => {
await page.waitForSelector('.feature-discovery-extrato button.hopscotch-cta', { timeout: 4000 })
.then(() => page.click('.feature-discovery-extrato button.hopscotch-cta')) // eslint-disable-line
.catch(() => {})
}

const stepClosePossiblePopup = async (page) => {
await page.waitForSelector('div.mfp-wrap', { timeout: 4000 })
.then(() => page.evaluate(() => popFechar())) // eslint-disable-line
Expand All @@ -110,17 +122,13 @@ const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}

const getFileFormatSelector = (options) => {
return '.TRNinput[value=' + options.file_format.toUpperCase() + ']'
}

const download = async (page, selector, finalFilePath) => {
const download = async (page, triggerDownload, finalFilePath, options) => {
const downloadPath = path.resolve(os.tmpdir(), 'download', uuid())
mkdirp(downloadPath)
console.log('Temporary downloading file to:', downloadPath)
await page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: downloadPath })

await page.click(selector)
await page.evaluate(triggerDownload, options.file_format)

const filename = await waitForFileToDownload(downloadPath)
const tempFilePath = path.resolve(downloadPath, filename)
Expand Down Expand Up @@ -167,4 +175,12 @@ const scraper = async (options) => {
console.log('Itaú scraper finished.')
}

/* eslint-disable */
String.prototype.interpolate = function (params) {
const names = Object.keys(params)
const vals = Object.values(params)
return new Function(...names, `return \`${this}\`;`)(...vals)
}
/* eslint-enable */

module.exports = scraper
Loading

0 comments on commit a35dfc6

Please sign in to comment.