casperjs というのを使って作ってみた。
コードは荒いが必要な方がいるかもしれないので、公開します。
使い方)
ここまで
※電子書籍の購入履歴は取得できません
※数量の取得もできません
コードは荒いが必要な方がいるかもしれないので、公開します。
casperjs のセットアップ(こちらが良いかも)後、下のamazon_csv.js を保存して、コマンドラインから次のように実行します。
使い方)
casperjs amazon_csv.js メールアドレス パスワード 対象年
例)
ここからamazon_csv.js
casperjs amazon_csv.js hoge@fugapiyo.co.jp password001 2014年
ここからamazon_csv.js
var casper = require('casper').create({ pageSettings: { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4' }, verbose: true, logLevel: 'debug' }); var email = casper.cli.get(0); var pass = casper.cli.get(1); var targetYear = casper.cli.get(2); var url = 'https://www.amazon.co.jp/gp/css/order-history'; var detailIdList = [], detailIdIndex = 0; var capId = 1; var csvDatas = []; function cap(){ casper.capture(capId++ + '.png'); } function dump(o){ require('utils').dump(o); } function setEidToDetail(){ var linkCandidates = document.querySelectorAll(".order .a-link-normal"); var map = Array.prototype.map; var filter = Array.prototype.filter; var id = 0; return map.call(filter.call(linkCandidates, function(e){ return '注文の詳細' == e.innerHTML; }), function(e) { var newId = 'secret' + id++; e.setAttribute('id', newId) return newId; }); } casper.start(url); // ログイン casper.then(function() { this.fill('form#ap_signin_form', { email: email, password: pass }, true); }); // 期間を選択するプルダウンをクリック casper.thenClick('#a-autoid-1 .a-dropdown-prompt') // 指定の年を選択 casper.then(function(){ var id = this.evaluate(function(targetYear){ var liList = document.getElementById('1_dropdown_combobox').getElementsByTagName('li'); for (var i = 0; i < liList.length; i++){ var li = liList[i]; var a = li.childNodes[0]; if (a.innerHTML.trim() == targetYear){ return a.id; } } }, targetYear); if (! id){ throw 'no such year ' + targetYear; } casper.thenClick('#' + id); }); // 詳細画面へのリンク一覧を取得 function first(){ debugger; detailIdIndex = 0 loop.call(this); } // 詳細画面へ遷移し、csv 情報を取得 function loop(){ detailIdList = this.evaluate(setEidToDetail); if (detailIdIndex < detailIdList.length){ var eId = detailIdList[detailIdIndex++] this.thenClick('#' + eId); casper.then(function(){ var datas = this.evaluate(function (){ function scrapeDetailNormal(){ // 注文日 var date = document.getElementsByClassName('order-date-invoice-item')[0].childNodes[0].textContent.replace(/注文日/, '').trim(); // 注文番号 var order = document.getElementsByClassName('order-date-invoice-item')[1].childNodes[0].textContent.replace(/注文番号/, '').trim(); var items = document.querySelectorAll('.a-fixed-left-grid'); var result = []; for (var i = 0; i < items.length; i++){ var item = items[i]; item.getElementsByClassName('a-row').childNode // 商品名 var name = item.getElementsByClassName('a-row')[0].getElementsByTagName('a')[0].innerHTML.trim() // 金額 var price = item.getElementsByClassName('a-color-price')[0].innerHTML.trim() // 販売 var shopEl = item.getElementsByClassName('a-color-secondary')[0] var shopAEl = shopEl.getElementsByTagName('a'); if (0 < shopAEl.length){ var shop = shopAEl[0].innerHTML; }else{ var shop = shopEl.innerHTML; } shop = shop.replace(/販売:/, '').trim() result.push({ date:date, order:order, name:name, price:price, shop:shop }); } return result; } if (0 < document.getElementsByTagName('h1').length){ return scrapeDetailNormal(); }else{ // TODO 電子書籍は難しい return []; } }); csvDatas = csvDatas.concat(datas); }); casper.then(function(){ casper.back(); }); casper.then(function(){ loop.call(this); }); }else{ last.call(this); } } // 次のページがあれば遷移してループを続ける function last(){ var nextId = this.evaluate(function(){ var lastEls = document.getElementsByClassName('a-last')[0].getElementsByTagName('a'); if (0 < lastEls.length){ var a = lastEls[0]; if (0 < a.className.indexOf('disabled')){ return; } var id = 'go-to-next-page'; a.setAttribute('id', id); return id; } }); this.then(function(){ debugger; if (nextId){ this.thenClick('#' + nextId, function(){ first.call(this); }); }else{ var csv = []; for (var i = 0; i < csvDatas.length; i++){ var data = csvDatas[i]; if (! data){ continue; } var list = []; list.push(data.date); list.push(data.order); list.push(data.shop); list.push(data.name); list.push(data.price); for (var j = 0; j < list.length; j++){ list[j] = '"' + list[j].replace(/"/g, '""') + '"'; } var line = list.join(','); csv.push(line); } for (var i = 0; i < csv.length; i++){ this.echo(csv[i]); } } }); } // ループ開始 casper.then(function() { first.call(this); }); casper.run();
ここまで
※電子書籍の購入履歴は取得できません
※数量の取得もできません
本日 2014/2/19 時点では動くが、いつかデザインが変わったら動かなくなると思う。
お約束ではありますが、試される方は全て自己責任でお願いします。
0 件のコメント:
コメントを投稿