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 件のコメント:
コメントを投稿