家計簿を一括ダウンロード,その2
FireFoxのコンソールで実行すると,ページをパースして,管理IDごとCSVに保存。
MoneyforwardのWeb上でカテゴリを変更するのが面倒だから,
Excelで編集して反映したいけど,CSVのアップロードではできない。
なので,一括変更のScriptを作成中。
とりあえず,管理IDがダウンロードできたから,
次はアップデートの方かな。
var downloadAsTextFile = function(fileName, content) { var a = document.createElement('a'); a.download = fileName; a.href = (window.URL || window.webkitURL).createObjectURL(new Blob([new Uint8Array([0xEF, 0xBB, 0xBF]), content])); document.body.appendChild(a); a.click(); document.body.removeChild(a); }; var downloadAsCSVFile = function(fileName, rows) { var content = ""; for(var i in rows) { for (var j = 0, m = rows[i].length; j < m; ++j) content += '"' + ("" + rows[i][j]).replace(/"/g, '""') + '"' + (j !== m ? ',' : ''); content += '\n'; } downloadAsTextFile(fileName, content); }; var parseListBody = function(text, rows) { var dom = eval("$" + text.match(/list_body.*?(\(.*)/)[1]); $(dom.filter("tr").get().reverse()).each((i, tr) => { /* $("td", tr).each((j, td) => { rows.push(["tbl", i, j, td.className, $(td).text().trim(), $(td).prop('outerHTML').replace(/[\n\r]/g,"").trim()]); }); */ //var form = $("form", tr).serializeArray(); var id = $("input[name*='\[id\]']", tr).val(); var lctg_id = $("input[name*='\[large_category_id\]']", tr).val(); var mctg_id = $("input[name*='\[middle_category_id\]']", tr).val(); var hash = $("input[name*='\[sub_account_id_hash\]']", tr).val(); var income = $("input[name*='\[is_income\]']", tr).val(); var target = $("input[name*='\[is_target\]']", tr).val()||""; var td_date = $("td.date", tr); var date_id = td_date.attr("data-table-sortable-value"); var date_str = td_date.text().trim(); var content = $("td.content div span", tr).text().trim(); var amount = $("td.amount span.offset, td.amount div.noform", tr).text().trim(); var amount_memo = $("td.amount div.offset", tr).text().trim(); var pull_right = $("td.amount div.pull-right", tr).text().trim(); var note = $("td.note, td.sub_account_id_hash span", tr).text().trim(); var explain = $("td.calc[title]", tr).attr("title"); var transfer_from = $($("td.calc div.transfer_account_box", tr).parent().prop('outerHTML')).children().empty().parent().text().trim(); var transfer_to = $("td.calc div.transfer_account_box", tr).text().trim(); var lctg = $("td.lctg", tr).text().trim(); var mctg = $("td.mctg", tr).text().trim(); var memo = $("td.memo", tr).text().trim(); rows.push([id, income, target, date_id.substr(0, 10), date_id, date_str, content, amount, amount_memo, pull_right, note, transfer_from, transfer_to, explain, lctg_id, lctg, mctg_id, mctg, memo, hash]); //rows.push([]); }); }; var Queue = function() { this.promise = Promise.resolve(true); this.addAsync = (action) => this.promise = this.promise.then(() => new Promise((resolve) => action(resolve))); this.addSync = (action) => this.addAsync((resolve) => { action(); resolve(); }); this.delay = (delay) => this.addAsync((resolve) => setTimeout(resolve, delay)); }; var getList = (q, rows, year, month) => { q.addAsync((resolve) => { $.ajax({ dataType: "text", type: "POST", url: "https://moneyforward.com/cf/fetch", data: { account_id_hash: "", from: year + "/" + month + "/1", service_id: "" }, headers: { "X-CSRF-Token": $("meta[name=csrf-token]").attr("content") } }).done((text) => { console.log(year + "/" + month + "/1"); parseListBody(text, rows); resolve(); }); }); }; var q = new Queue(); var rows = [["id", "income", "target", "date", "date_id", "date_str", "content", "amount", "amount_memo", "pull_right", "note", "transfer_from", "transfer_to", "explain", "lctg_id", "lctg", "mctg_id", "mctg", "memo", "hash"]]; for(var y = 2010; y <= 2018; ++y) { for(var m = 1; m <= 12; ++m) { getList(q, rows, y, m); } } q.addSync(() => downloadAsCSVFile("hoge.csv", rows)); q.addSync(() => alert("完了"));
(()=>{ var Queue = function() { this.promise = Promise.resolve(true); this.addAsync = (action) => this.promise = this.promise.then(() => new Promise((resolve) => action(resolve))); this.addSync = (action) => this.addAsync((resolve) => { action(); resolve(); }); this.delay = (delay) => this.addAsync((resolve) => setTimeout(resolve, delay)); }; var q = new Queue(); var jqxhr, jqxhr2; var sub_win_option = "top=0,left=0,width=500,height=500,scrollbars=1,location=0,menubar=0,toolbar=0,status=1,directories=0,resizable=1"; var sv_win = window.open(window.location, "show_view_window", sub_win_option); $(sv_win.document).ready(() => { var w = $(window); var st = w.scrollTop(), sb = st + w.height(); var sub; q.delay(2000); q.addSync(() => { sub = $(sv_win.document.body); sub.empty(); }); $('a._work, a.gtm-thumbnail-link').each((i,v) => { var a = $(v); var t = a.offset().top; if(st < t && t < sb) { var href = a.attr('href'); var is_manga = $('.page-count, ._1VJYUl1', a ).length > 0; var fetch_manga = (resolve) => { var url = href.replace(/mode=medium/, "mode=manga"); console.log("fetch_manga", url); if(jqxhr2) { jqxhr2.abort(); } jqxhr2 = $.ajax({ url: url }).done( (data) => { $('section.manga img', data).each((i, e) => { $('<img/>').attr("src", $(e, data).attr('data-src')).css({ "max-width": "-moz-available" }).appendTo(sub); }); resolve(); }).fail((jqXHR, textStatus, errorThrown) => { console.log('fail', jqXHR.status); resolve(); }); }; var fetch_image = (resolve) => { console.log("fetch_image", href); if(jqxhr) { jqxhr.abort(); } jqxhr = $.ajax({ url: href }).done( (data) => { var img = $("img.original-image", data); if(img.length > 0) { $('<img/>').attr("src", img.attr('data-src')).css({ "max-width": "-moz-available" }).appendTo(sub); resolve(); } else { fetch_manga(resolve); } }); }; q.addAsync((resolve) => { //console.log(is_manga, href); if( is_manga ) { fetch_manga(resolve); } else { fetch_image(resolve); } }); } }); }); })();