Amazon の自動購入プログラミングをやってみる(NodeJS)

先日インストールした CasperJS を使って Amazon サイトの自動購入処理を行うプログラミングを作成してみました。

環境

  • Arch Linux
  • PhantomJS
  • CasperJS

参考文献

プログラム

普段加湿器のアロマで使用しているオイルを自動購入するプログラムを作成します。

ソースコード
// onlineShopping.js

var AZ_EMAIL = 'XXXXXXXX';      // Amazon ID
var AZ_PASSWD = 'XXXXXXXX';     // Amazon password

var casper = require('casper').create({
        pageSettings: {
                loadImages: false,
                loadPlugins: false
        },
        waitTimeout: 30000,
        verbose: true
});

// iPhone 画面としてブラウザ操作する。
casper.userAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OSX) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53');

// ログイン画面へアクセスする。
casper.start('https://www.amazon.co.jp/ap/signin?_encoding=UTF8&openid.assoc_handle=jpflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.co.jp%2F%3Fref_%3Dnav_signin', function() {
        this.echo(this.getTitle());
        this.capture('capture1.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('form[name="signIn"]', function() {
                this.evaluate(function(email, passwd) {
                        document.querySelector('#ap_email').value = email;
                        document.querySelector('#ap_password').value = passwd;
                }, AZ_EMAIL, AZ_PASSWD);
        });
});

// ログインする。
casper.then(function() {
        this.capture('capture2.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('form[name="signIn"]', function() {
                this.evaluate(function() {
                        document.querySelector('#signInSubmit').click();
                });
        });
});

// 商品の画面へアクセスする。
casper.then(function() {
        this.capture('capture3.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('#nav-logo', function() {
                this.open('https://www.amazon.co.jp/dp/B000FQR2BO/');
        });
});

// カードに入れる。
casper.then(function() {
        this.echo(this.getTitle());
        this.capture('capture4.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('#add-to-cart-button', function() {
                this.evaluate(function() {
                        document.querySelector('#add-to-cart-button').click();
                });
        });
});

// レジへ進む。
casper.then(function() {
        this.capture('capture5.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('#a-autoid-2-announce', function() {
                this.evaluate(function() {
                        document.querySelector('#a-autoid-2-announce').click();
                });
        });
});

// 注文を確定する。
casper.then(function() {
        this.echo(this.getTitle());
        this.capture('capture6.png', {top:0, left:0, width:1280, height:720});
        this.waitForSelector('input[name="placeYourOrder1"]', function() {
                this.echo('click click');
                this.evaluate(function() {
                        document.querySelector('input[name="placeYourOrder1"]').click();
                });
        });
});

casper.then(function() {
        this.echo(this.getTitle());
        this.capture('capture7.png', {top:0, left:0, width:1280, height:720});
});

casper.run();
コード解説

「getTitle」と「capture」を使用している箇所は、処理が正常に進んでいるかの確認のためなので主処理には無関係です。

「userAgent」を使用するとブラウザ指定や端末の種別指定ができます。ユーザーエージェントの指定によって画面の構成などが変わります。こちらのサイトでユーザーエージェントの一覧が参照できます。
いろいろと試した結果、今回は iPhone 端末上でオンライン注文する操作にしました。

「waitForSelector」を呼び出すと、第1引数で指定したセレクタが機能できるまで画面描画を待った後、第2引数で指定した処理を行います。指定したセレクタが画面上に存在しない場合はタイムアウトエラーになります。操作を確実に行うためにボタン操作はこの関数を使って行います。

後書き

今回は注文操作のために CasperJS を利用してプログラムを作成しましたが、使ってみてこのツールの便利さがわかりました。画面のキャプチャやセレクタの情報をログに履いたりとテストツールとして本当に素晴らしいです。CasperJS の公式サイトを見ると他にいろいろとできそうですのでたくさん試してみたいです。