Last active
December 25, 2019 14:57
-
-
Save matisnape/29136ac9b98f0557039f84f291586429 to your computer and use it in GitHub Desktop.
scrape credit card transactions from mbank
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Disclaimers: | |
1. The script works for currently loaded transactions, so make sure to set the correct date range. | |
2. Supports only credit card history and only transactions that are already booked. | |
3. No data is saved by the script to third party locations | |
*/ | |
class CreditHistoryScraper { | |
transactions() { | |
return Array.from( | |
document.querySelectorAll('table tr[data-test-id*="history:operationRow:"]') | |
) | |
} | |
openTransactionDetails(transactionEl) { | |
const TRANSACTION_VIEW = this.getElementByXpath("//tr//*[@style='height: auto; overflow: visible;']"); | |
transactionEl.click(); | |
for (let i = 0; i < 3; i++) { | |
if (TRANSACTION_VIEW == null) | |
this.wait(500); | |
else { | |
console.log("Transaction details visible") | |
break; | |
} | |
} | |
} | |
saveDetailsForCSV(arr) { | |
const MEMO_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:OperationType')]"); | |
const AMOUNT_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:OperationAmount')]"); | |
const PAYEE_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:MerchantName')]"); | |
const DATE_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:SettlementDate')]"); | |
if (MEMO_COL != null && AMOUNT_COL != null && PAYEE_COL != null) { | |
arr.push( | |
[ | |
DATE_COL.innerText, | |
MEMO_COL.innerHTML.replace(/,/g, ' '), | |
PAYEE_COL.innerHTML.replace(/,|#/g, ' '), | |
AMOUNT_COL.innerHTML.slice(0, -4).replace(/,/g, '.') | |
] | |
) | |
} | |
} | |
parseToCSVAndSaveFile(arr) { | |
let csvContent = "data:text/csv;charset=utf-8,"; | |
arr.forEach(function(rowArray){ | |
let row = rowArray.join(","); | |
csvContent += row + "\r\n"; | |
}); | |
let encodedUri = encodeURI(csvContent); | |
const link = document.createElement("a"); | |
link.setAttribute("href", encodedUri); | |
link.setAttribute("download", "YNAB_ready" + Date.now() + ".csv"); | |
link.click(); | |
} | |
wait(ms) { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
}; | |
getElementByXpath(path) { | |
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
} | |
async start() { | |
const arr = [['DATE','MEMO','PAYEE','AMOUNT']]; | |
// need to initialize transactions now | |
const transactionsArr = this.transactions(); | |
for (let transactionEl of transactionsArr) { | |
// 1. open each transaction to enable selectors | |
this.openTransactionDetails(transactionEl); | |
await this.wait(1000); | |
// 2. save data to arr | |
this.saveDetailsForCSV(arr); | |
await this.wait(1000); | |
}; | |
await this.wait(1000); | |
// 3. initialize CSV format and append content | |
this.parseToCSVAndSaveFile(arr); | |
} | |
} | |
let chs = new CreditHistoryScraper(); | |
chs.start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Disclaimers: | |
1. The script works for currently loaded transactions, so make sure to set the correct date range. | |
2. Supports only credit card history and only transactions that are already booked. | |
3. No data is saved by the script to third party locations | |
*/ | |
class CreditHistoryScraper { | |
transactions() { | |
return Array.from( | |
document.querySelectorAll('table tr[data-test-id*="history:operationRow:"]') | |
) | |
} | |
openTransactionDetails(transactionEl) { | |
const TRANSACTION_VIEW = this.getElementByXpath("//tr//*[@style='height: auto; overflow: visible;']"); | |
transactionEl.click(); | |
for (let i = 0; i < 3; i++) { | |
if (TRANSACTION_VIEW == null) | |
this.wait(500); | |
else { | |
console.log("Transaction details visible") | |
break; | |
} | |
} | |
} | |
saveDetailsForCSV(arr) { | |
const MEMO_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:OperationType')]"); | |
const AMOUNT_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:OperationAmount')]"); | |
const PAYEE_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:MerchantName')]"); | |
const DATE_COL = this.getElementByXpath( | |
"//tr//*[@style='height: auto; overflow: visible;']//*[contains(@data-test-id, 'GenericDetails:SettlementDate')]"); | |
if (MEMO_COL != null && AMOUNT_COL != null && PAYEE_COL != null) { | |
arr.push( | |
[ | |
DATE_COL.innerText, | |
MEMO_COL.innerHTML.replace(/,/g, ' '), | |
PAYEE_COL.innerHTML.replace(/,|#/g, ' '), | |
AMOUNT_COL.innerHTML.slice(0, -4).replace(/,/g, '.') | |
] | |
) | |
} | |
} | |
parseToCSVAndSaveFile(arr) { | |
let csvContent = "data:text/csv;charset=utf-8,"; | |
arr.forEach(function(rowArray){ | |
let row = rowArray.join(","); | |
csvContent += row + "\r\n"; | |
}); | |
let encodedUri = encodeURI(csvContent); | |
const link = document.createElement("a"); | |
link.setAttribute("href", encodedUri); | |
link.setAttribute("download", "YNAB_ready" + Date.now() + ".csv"); | |
link.click(); | |
} | |
wait(ms) { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
}; | |
getElementByXpath(path) { | |
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
} | |
async start() { | |
const arr = [['DATE','MEMO','PAYEE','AMOUNT']]; | |
// need to initialize transactions now | |
const transactionsArr = this.transactions(); | |
for (let transactionEl of transactionsArr) { | |
// 1. open each transaction to enable selectors | |
this.openTransactionDetails(transactionEl); | |
await this.wait(1000); | |
// 2. save data to arr | |
this.saveDetailsForCSV(arr); | |
await this.wait(1000); | |
}; | |
await this.wait(1000); | |
// 3. initialize CSV format and append content | |
this.parseToCSVAndSaveFile(arr); | |
} | |
} | |
let chs = new CreditHistoryScraper(); | |
chs.start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Disclaimers: | |
1. The script works for currently loaded transactions, so make sure to set the correct date range. | |
2. Supports only regular account history and only transactions that are already booked. | |
3. No data is saved by the script to third party locations | |
*/ | |
const i = document.createElement("iframe"); | |
i.style.display = "none"; | |
document.body.appendChild(i); | |
window.console = i.contentWindow.console; | |
const emax = "31 1140 2004 0000 3002 7447 8183"; | |
const emaxplus = "29 1140 2004 0000 3102 7447 8170"; | |
const ekonto = "23 1140 2004 0000 3802 3986 7850"; | |
const ekonto2 = "82 1140 2004 0000 3202 7830 4884"; | |
const ekonto3 = "26 1140 2004 0000 3602 7830 5405"; | |
const lokaty = "29 1140 2004 0000 3102 7447 8170"; | |
const cel = "93 1140 2004 0000 3302 7453 6866"; | |
class AccountHistoryScraper { | |
constructor() { | |
this.n = 0; | |
} | |
transactions() { | |
return Array.from( | |
document.querySelectorAll("span.content-list-type-icon:not([data-original-title='Nierozliczone'])")); | |
} | |
openTransactionDetails(transactionEl) { | |
transactionEl.click(); | |
} | |
saveDetailsForCSV(arr) { | |
const MEMO_COL = this.getElementByXpath("//tr[th[contains(text(), 'Rodzaj operacji')]]/td").innerHTML; | |
if (MEMO_COL == "PRZELEW REGULARNE OSZCZĘDZANIE" || MEMO_COL == "PRZELEW NA TWOJE CELE") { | |
arr.push( | |
[ | |
regularne.date_col, | |
"", | |
regularne.payee_col, | |
"-" + regularne.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL == "ZAKUP PRZY UŻYCIU KARTY") { | |
arr.push( | |
[ | |
karta.date_col, | |
MEMO_COL.replace(/,/g, " "), | |
karta.payee_col.replace(/,/g, " "), | |
karta.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("SPŁATA KARTY")) { | |
arr.push( | |
[ | |
splatakarty.date_col, | |
"", | |
splatakarty.payee_col, | |
"-" + splatakarty.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL == "PRZELEW WŁASNY") { | |
let account; | |
switch(przelewwlasny.odbiorca) { | |
case emax: | |
account = "emax"; | |
break; | |
case emaxplus: | |
account = "emaxplus"; | |
break; | |
case ekonto: | |
account = "ekonto"; | |
break; | |
case ekonto2: | |
account = "ekonto2"; | |
break; | |
case ekonto3: | |
account = "ekonto3"; | |
break; | |
case cel: | |
account = "Regularne Oszczedzanie"; | |
break; | |
} | |
arr.push( | |
[ | |
przelewwlasny.date_col, | |
MEMO_COL.replace(/,/g, " "), | |
przelewwlasny.payee_col(account), | |
"-" + przelewwlasny.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("PROWIZJA")) { | |
arr.push( | |
[ | |
prowizja.date_col, | |
"", | |
MEMO_COL.replace(/,/g, " "), | |
prowizja.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("MTRANSFER")) { | |
arr.push( | |
[ | |
mtransfer.date_col, | |
mtransfer.memo_col.replace(/,/g, " "), | |
mtransfer.payee_col.replace(/,/g, " "), | |
"-" + mtransfer.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("BLIK - ZAKUP")) { | |
arr.push( | |
[ | |
blik.date_col, | |
blik.memo_col.replace(/,/g, " "), | |
blik.payee_col.replace(/,/g, " "), | |
blik.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("PRZYCHODZĄCY")) { | |
// ignore incoming from own accounts | |
if (! [emax, ekonto, emaxplus].includes(incoming.nadawca) ) { | |
arr.push( | |
[ | |
incoming.date_col, | |
incoming.memo_col.replace(/,/g, " "), | |
incoming.payee_col.replace(/,/g, " "), | |
incoming.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} else { | |
console.log("Ignored incoming from own account: " + incoming.amount_col + " (" + incoming.date_col + ")") | |
} | |
} | |
else if (MEMO_COL.includes("WYCHODZĄCY") && ! MEMO_COL.includes("MTRANSFER") ) { | |
if (outgoing.rachunek_odbiorcy == lokaty) { | |
outgoing.payee_col = "Transfer to: Lokaty"; | |
} | |
arr.push( | |
[ | |
outgoing.date_col, | |
outgoing.memo_col.replace(/,/g, " "), | |
outgoing.payee_col().replace(/,/g, " "), | |
"-" + outgoing.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("MOKAZJE")) { | |
arr.push( | |
[ | |
mokazje.date_col, | |
mokazje.memo_col.replace(/,/g, " "), | |
mokazje.payee_col.replace(/,/g, " "), | |
mokazje.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("PODATEK")) { | |
arr.push( | |
[ | |
podatek.date_col, | |
podatek.memo_col.replace(/,/g, " "), | |
podatek.payee_col.replace(/,/g, " "), | |
"-" + podatek.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("KAPITALIZACJA")) { | |
arr.push( | |
[ | |
kapitalizacja.date_col, | |
kapitalizacja.memo_col.replace(/,/g, " "), | |
kapitalizacja.payee_col, | |
kapitalizacja.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("WYPŁATA")) { | |
arr.push( | |
[ | |
wyplata.date_col, | |
wyplata.memo_col.replace(/,/g, " "), | |
wyplata.payee_col, | |
wyplata.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else if (MEMO_COL.includes("WPŁATA")) { | |
arr.push( | |
[ | |
wplata.date_col, | |
wplata.memo_col.replace(/,/g, " "), | |
wplata.payee_col, | |
wplata.amount_col.slice(0, -4).replace(/,/g, ".") | |
] | |
); | |
} | |
else { | |
this.n+=1; | |
console.log(this.n + ". Didn't recognize: " + MEMO_COL); | |
} | |
} | |
parseToCSVAndSaveFile(arr) { | |
let csvContent = "data:text/csv;charset=utf-8,"; | |
arr.forEach(function(rowArray){ | |
let row = rowArray.join(","); | |
csvContent += row + "\r\n"; | |
}); | |
let encodedUri = encodeURI(csvContent); | |
const link = document.createElement("a"); | |
link.setAttribute("href", encodedUri); | |
link.setAttribute("download", "YNAB_ready" + Date.now() + ".csv"); | |
link.click(); | |
} | |
wait(ms) { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
} | |
getElementByXpath(path) { | |
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
} | |
async start() { | |
const arr = [["DATE","MEMO","PAYEE","AMOUNT"]]; | |
// need to initialize transactions now | |
const transactionsArr = this.transactions(); | |
for (let transactionEl of transactionsArr) { | |
// 1. open each transaction to enable selectors | |
this.openTransactionDetails(transactionEl); | |
await this.wait(2000); | |
// 2. save data to arr | |
this.saveDetailsForCSV(arr); | |
await this.wait(1200); | |
}; | |
await this.wait(1200); | |
// 3. initialize CSV format and append content | |
this.parseToCSVAndSaveFile(arr); | |
console.log("Number of rows in CSV: " + (arr.length - 1)); | |
} | |
} | |
class Transakcja { | |
get memo_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Rodzaj operacji')]]/td").innerHTML; | |
} | |
getElementByXpath(path) { | |
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
} | |
} | |
class RegularneOszczedzanie extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Transfer: Regularne Oszczedzanie"; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
} | |
class ZakupKarta extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota w walucie rachunku')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Nazwa odbiorcy')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data rozliczenia')]]/td").innerHTML; | |
} | |
} | |
class SplataKarty extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Payment: kredytówka"; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
} | |
class PrzelewWlasny extends Transakcja { | |
get odbiorca() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Rachunek odbiorcy')]]/td").innerHTML; | |
} | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
payee_col(account) { | |
return "Transfer: " + account; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
} | |
class Prowizja extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota w walucie rachunku')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data rozliczenia')]]/td").innerHTML; | |
} | |
} | |
class Mtransfer extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Nazwa odbiorcy')]]/td").innerHTML; | |
} | |
get memo_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Tytuł przelewu')]]/td").innerHTML; | |
} | |
} | |
class Blik extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota w walucie rachunku')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Nazwa sklepu internetowego')]]/td").innerHTML; | |
} | |
get memo_col() { | |
return "Blik: " + this.getElementByXpath("//tr[th[contains(text(), 'Nr operacji BLIK')]]/td").innerHTML; | |
} | |
} | |
class PrzelewWychodzacy extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
payee_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Nazwa odbiorcy')]]/td").innerHTML; | |
} | |
get memo_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Tytuł przelewu')]]/td").innerHTML; | |
} | |
get rachunek_odbiorcy() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Rachunek odbiorcy')]]/td").innerHTML; | |
} | |
} | |
class PrzelewPrzychodzacy extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Nazwa nadawcy')]]/td").innerHTML; | |
} | |
get memo_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Tytuł przelewu')]]/td").innerHTML; | |
} | |
get nadawca() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Rachunek nadawcy')]]/td").innerHTML; | |
} | |
} | |
class Mokazje extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Mokazje"; | |
} | |
get memo_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Tytuł operacji')]]/td").innerHTML; | |
} | |
} | |
class Podatek extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Podatek od odsetek"; | |
} | |
} | |
class Kapitalizacja extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Kapitalizacja odsetek"; | |
} | |
} | |
class Wyplata extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota w walucie rachunku')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data operacji')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Transfer: Gotówka"; | |
} | |
} | |
class Wplata extends Transakcja { | |
get amount_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Kwota operacji')]]/td").innerHTML; | |
} | |
get date_col() { | |
return this.getElementByXpath("//tr[th[contains(text(), 'Data księgowania')]]/td").innerHTML; | |
} | |
get payee_col() { | |
return "Transfer: Gotówka"; | |
} | |
} | |
// const karta = new ZakupKarta(); | |
// const regularne = new RegularneOszczedzanie(); | |
// const splatakarty = new SplataKarty(); | |
// const przelewwlasny = new PrzelewWlasny(); | |
// const prowizja = new Prowizja(); | |
// const mtransfer = new Mtransfer(); | |
// const blik = new Blik(); | |
// const incoming = new PrzelewPrzychodzacy(); | |
// const outgoing = new PrzelewWychodzacy(); | |
// const mokazje = new Mokazje(); | |
// const podatek = new Podatek(); | |
// const kapitalizacja = new Kapitalizacja(); | |
// const wplata = new Wplata(); | |
// const wyplata = new Wyplata(); | |
// const ahs = new AccountHistoryScraper(); | |
// ahs.start(); | |
const karta = new ZakupKarta(); | |
const regularne = new RegularneOszczedzanie(); | |
const splatakarty = new SplataKarty(); | |
const przelewwlasny = new PrzelewWlasny(); | |
const prowizja = new Prowizja(); | |
const mtransfer = new Mtransfer(); | |
const blik = new Blik(); | |
const incoming = new PrzelewPrzychodzacy(); | |
const outgoing = new PrzelewWychodzacy(); | |
const mokazje = new Mokazje(); | |
const podatek = new Podatek(); | |
const kapitalizacja = new Kapitalizacja(); | |
const wplata = new Wplata(); | |
const wyplata = new Wyplata(); | |
const ahs = new AccountHistoryScraper(); | |
ahs.start(); | |
// WYPŁATA W BANKOMACIE | |
// WPŁATA WE WPŁATOMACIE | |
// PRZELEW WŁASNY | |
// ZAKUP PRZY UŻYCIU KARTY | |
// RĘCZNA SPŁATA KARTY KREDYT. | |
// PROWIZJA | |
// PRZELEW MTRANSFER WYCHODZACY | |
// BLIK | |
// PRZELEW WEWNĘTRZNY PRZYCHODZĄCY | |
// PRZELEW ZEWNĘTRZNY PRZYCHODZĄCY | |
// PRZELEW WEWNĘTRZNY WYCHODZĄCY | |
// PRZELEW ZEWNĘTRZNY WYCHODZĄCY | |
// MOKAZJE UZNANIE | |
// PODATEK OD ODSETEK KAPITAŁOWYCH | |
// KAPITALIZACJA ODSETEK | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Disclaimers: | |
1. The script works for currently loaded transactions, so make sure to set the correct date range. | |
2. Supports only credit card history and only transactions that are already booked. | |
3. No data is saved by the script to third party locations | |
*/ | |
class CreditHistoryScraper { | |
transactions() { | |
return Array.from( | |
document.querySelectorAll("[data-original-title='Płatność kartą']")) | |
} | |
openTransactionDetails(transactionEl) { | |
transactionEl.click(); | |
} | |
saveDetailsForCSV(arr) { | |
const MEMO_COL = this.getElementByXpath("//tr[th[contains(text(), 'Rodzaj operacji')]]/td").innerHTML; | |
const AMOUNT_COL = this.getElementByXpath("//tr[th[contains(text(), 'Kwota w walucie rachunku')]]/td").innerHTML; | |
const PAYEE_COL = this.getElementByXpath("//tr[th[contains(text(), 'Miejsce transakcji')]]/td").innerHTML; | |
const DATE_COL = this.getElementByXpath("//tr[th[contains(text(), 'Data rozliczenia')]]/td").innerHTML; | |
arr.push( | |
[ | |
DATE_COL, | |
MEMO_COL.replace(/,/g, ' '), | |
PAYEE_COL.replace(/,/g, ' '), | |
AMOUNT_COL.slice(0, -4).replace(/,/g, '.') | |
] | |
) | |
} | |
parseToCSVAndSaveFile(arr) { | |
let csvContent = "data:text/csv;charset=utf-8,"; | |
arr.forEach(function(rowArray){ | |
let row = rowArray.join(","); | |
csvContent += row + "\r\n"; | |
}); | |
let encodedUri = encodeURI(csvContent); | |
const link = document.createElement("a"); | |
link.setAttribute("href", encodedUri); | |
link.setAttribute("download", "YNAB_ready" + Date.now() + ".csv"); | |
link.click(); | |
} | |
wait(ms) { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
}; | |
getElementByXpath(path) { | |
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
} | |
async start() { | |
const arr = [['DATE','MEMO','PAYEE','AMOUNT']]; | |
// need to initialize transactions now | |
const transactionsArr = this.transactions(); | |
for (let transactionEl of transactionsArr) { | |
// 1. open each transaction to enable selectors | |
this.openTransactionDetails(transactionEl); | |
await this.wait(600); | |
// 2. save data to arr | |
this.saveDetailsForCSV(arr); | |
await this.wait(1000); | |
}; | |
await this.wait(1000); | |
// 3. initialize CSV format and append content | |
this.parseToCSVAndSaveFile(arr); | |
} | |
} | |
const chs = new CreditHistoryScraper(); | |
chs.start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the shape influenced greatly by https://gist.github.com/poteto/0d1cb865f187edd38d9350caed5a6a38