-
-
Save kentaro/e87dd8ded59d25a24a6901a596755098 to your computer and use it in GitHub Desktop.
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
// Amazonの注文履歴をCSV形式にして出力するスクリプト | |
// | |
// 以下のスクリプトを参考に作成されました。 | |
// http://moroya.hatenablog.jp/entry/2013/06/03/225935 | |
// | |
// CSVに成型しているのは14行目から定義されているformatEntryという関数なので、これを書き換えれば自由な書式で出力できます。 | |
(function(){ | |
// 各注文履歴をCSVフォーマットにして返す | |
var datePattern = new RegExp("(\\d{4})年(\\d{1,2})月(\\d{1,2})日"); | |
function formatEntry(entry) { | |
entry.date.match(datePattern); | |
var year = RegExp.$1; | |
var month = RegExp.$2; if (month.length <= 1) month = "0" + month; | |
var day = RegExp.$3; if (day.length <= 1) day = "0" + day; | |
var item = entry.item.split("\"").join("\"\""); | |
//for private use: | |
return year + month + day + "," + entry.price + ",\"Amazon: " + item + "\"\n"; | |
} | |
// 一つの注文に含まれる複数の物品名をつなぐ文字列 | |
var itemDelimiter = " / "; | |
var total = {}; | |
var year = '2019'; | |
var all = false; | |
function init(num) { | |
if(typeof num !== 'number') { | |
num = 0; | |
$('<div/>').css({ | |
position: 'fixed', | |
left: 0, | |
top: 0, | |
width: '100%', | |
height: '100%', | |
zIndex: 1000, | |
backgroundColor: 'rgba(0,0,0,.7)', | |
color: '#fff', | |
fontSize: 30, | |
textAlign: 'center', | |
paddingTop: '15em' | |
}).attr('id', '___overlay').text('Amazonいくら使った?').appendTo('body'); | |
year = window.prompt('何年分の注文を集計しますか?\n - 半角数字4桁で入力してください\n - 全期間を集計する場合は「all」と入力します', year); | |
if(year === 'all') { | |
all = true; | |
year = $('div.top-controls select option:last').val().match(/[0-9]/g).join(''); | |
} else if(!/^[0-9]{4}$/.test(year)) { | |
alert('正しい数値を入力してください'); | |
$('#___overlay').remove(); | |
return false; | |
} | |
year = Number(year); | |
} | |
var progress = load(num); | |
$('#___overlay').text(year+'年の集計中… / '+(num+1)+'ページ目'); | |
progress.done(function(results){ | |
if (typeof total[year] === 'undefined') { | |
total[year] = results; | |
} else { | |
total[year] = total[year].concat(results); | |
} | |
init(num+1); | |
}).fail(function(){ | |
if(all && new Date().getFullYear() > year) { | |
year++; | |
init(0); | |
} else { | |
var txt = 'あなたは\n'; | |
var _contents = ""; | |
var _total = 0; | |
$.each(total, function(year, results){ | |
var yen = 0; | |
$.each(results, function(){ | |
yen += this.price; | |
_contents += formatEntry(this); | |
}); | |
txt += year + '年 合計' + addFigure(yen) + '円分\n'; | |
_total += yen; | |
}); | |
if(all) txt += '総計' + addFigure(_total) + '円分\n'; | |
popup(_contents).alert(txt + 'の買い物をAmazonでしました!'); | |
var saveAsCsv = function() { | |
var blob = new Blob([_contents], {type: "text/plain; charset=utf-8"}); | |
saveAs(blob, "amazon.csv"); | |
}; | |
if(typeof saveAs !== 'function') { | |
var d=document; | |
var s=d.createElement('script'); | |
s.src='//cdn.rawgit.com/eligrey/FileSaver.js/master/FileSaver.min.js'; | |
s.onload=saveAsCsv; | |
d.body.appendChild(s); | |
} else { | |
saveAsCsv(); | |
} | |
$('#___overlay').remove(); | |
} | |
}); | |
} | |
function load(num) { | |
var df = $.Deferred(); | |
var page = get(num); | |
page.done(function(data){ | |
var dom = $.parseHTML(data); | |
var results = []; | |
$(dom).find('div.order').each(function(){ | |
var box = $(this); | |
var dateText = $(box.find('div.order-info span.value')[0]).text(); | |
var items = []; | |
box.find('div.a-row>a.a-link-normal').each(function(){ | |
items.push($(this).text().trim()); | |
}); | |
var item = items.join(itemDelimiter); | |
var priceText = $(box.find('div.order-info span.value')[1]).text(); | |
var price = Number(priceText.match(/[0-9]/g).join('')); | |
console.log(item, price); | |
results.push({'date':dateText,'item':item,'price':price}); | |
}); | |
if(results.length <= 0) df.reject(); | |
else df.resolve(results); | |
}); | |
return df.promise(); | |
} | |
function get(num) { | |
var df = $.Deferred(); | |
$.ajax({ | |
url: 'https://www.amazon.co.jp/gp/css/order-history?digitalOrders=1&unifiedOrders=1&orderFilter=year-'+year+'&startIndex='+num*10, | |
beforeSend: function (xhr){ | |
xhr.setRequestHeader('X-Requested-With', {toString: function(){ return ''; }}); | |
}, | |
}) | |
.success(function(data){ | |
df.resolve(data); | |
}) | |
.fail(function(jqXHR, msg){ | |
console.log("fail",msg); | |
}); | |
return df.promise(); | |
} | |
function addFigure(str) { | |
var num = new String(str).replace(/,/g, ""); | |
while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2"))); | |
return num; | |
} | |
function popup(content) { | |
var generator=window.open('','name','height=250,width=700'); | |
generator.document.write('<html><head><title>Amazon to CSV</title>'); | |
generator.document.write('</head><body>'); | |
generator.document.write('<pre>'); | |
generator.document.write(escapeHtml(content)); | |
generator.document.write('</pre>'); | |
generator.document.write('</body></html>'); | |
generator.document.close(); | |
return generator; | |
} | |
var entityMap = { | |
"&": "&", | |
"<": "<", | |
">": ">", | |
'"': '"', | |
"'": ''', | |
"/": '/' | |
}; | |
var entityPattern = new RegExp("[&<>\"'\/]", "g"); | |
function escapeHtml(string) { | |
return String(string).replace(entityPattern, function (s) { | |
return entityMap[s]; | |
}); | |
} | |
// if(typeof $ !== 'function') { | |
var d=document; | |
var s=d.createElement('script'); | |
s.src='//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'; | |
s.onload=init; | |
d.body.appendChild(s); | |
// } else { | |
init(); | |
// } | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment