「楽天 ラッキーくじ」を自動化して、運試しをしてみる Tampermonkey篇

#今回やること

昨年の [Seleniumによるくじ引き](https://qiita.com/QDM/items/4db022e7adcc004a6db3) に変えて、今年はGoogle Chrome 拡張機能の [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja) を使って「楽天 ラッキーくじ」を自動化して、クリスマスの25日まで運だめしをしてみます。

Seleniumは自由度が高く、やれることも多いのですが、環境の準備がいろいろと面倒なので、今回はよりお手軽なTampermonkeyを利用してみます。

#「楽天 ラッキーくじ」とは

楽天会員であれば、誰でもPCブラウザやスマホで引けるくじです。1日1回引くことができます。くじに当たれば、楽天ポイントを獲得できます。

[【楽天】ラッキーくじ一覧](https://kuji.rakuten.co.jp/)

当選確率はそれほど高くないですが、数十回に1回程度は当たるようです。様々なくじがあり、数が多いので、毎日まとめて引けば当選のチャンスを増やせそうです。数打ちゃ当たる作戦ですね。

今回は、有志の方が、定時開催の楽天くじに加えて、期間限定の特別キャンペーンくじ（当選確率が高め）も合わせて、随時まとめてくださっている [楽天ラッキーくじ一覧](https://rakucoin.appspot.com/rakuten/kuji/)（非公式）をありがたく利用させていただきます。また、「PC版ラッキーくじ」のみに限定しました。

#事前準備

- 楽天アカウントの登録
- Google Chrome 最新版
- 拡張機能 [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja) のセットアップ。Chromeウェブストアから、拡張機能を入れてください。
- 楽天から様々なメールが送られてきても動じない覚悟（くじを引くと、楽天から様々な宣伝DMが送られてきます）

#Tampermonkeyを使った自動処理の考え方

Tampermonkeyは、WEBページ上に任意のJavaScriptを差し込むことで、各種操作を行うことができるChrome拡張機能です。Tampermonkeyを使えば、ブラウザ操作をマクロ的に自動化することも可能になります。

すべての操作が可能なわけではありませんが、ブラウザ上でJavaScriptが出来る範囲のことであれば、ある程度のことは出来そうです。うまく使えば、簡易的なRPAとしても活用できるでしょう。

**Tampermonkeyを利用した参考事例:**

- [【画面操作】ワンクリックでWebページからプレゼント応募しまくる](https://qiita.com/kitayama_y/items/7e40b1a5b7d969dbcbaf)
- [クリックポストで連続自動支払いしてみた](https://qiita.com/yu_bookstore/items/a599930b7fde7e53f429)
- [環境構築なしでブラウザの自動操作を行う](https://qiita.com/sagami1991/items/794168cf14ed198d6372)

くじ引きを自動化するにあたり、今回作成したTampermonkey用のJavaScriptでは、「ページ内の要素の取得」、「一度のみ行う処理」、「くり返し行う処理」を組み合わせただけです。

## ページ内の要素の取得

まず、操作を行いたいページ内のHTML要素を取得するところから始めます。querySelectorAll() を使って、ページ内から必要な要素を取得します。要素の取得方法は、様々なやり方やテクニックがありますが、今回は簡単なことしかやっていません。


```javascript
// 例1: tableタグのclassが "table" の要素を取得する
var linklist = document.querySelectorAll('table[class="table"]');

// 例2: 取得した各table要素内の aタグ を取得する
kujiPC = linklist[0].querySelectorAll('a');
kujiSP = linklist[1].querySelectorAll('a');
kujiOther = linklist[2].querySelectorAll('a');
```

## 1度のみ行う処理 と 繰り返し行う処理

setTimeout() と setInterval() を使って、処理コードを記述していきます。それぞれ、実行タイミングをミリ秒数で設定して、1度のみ行う処理と、くり返し行う処理を使い分けます。

```javascript
// 1度のみ行う処理
setTimeout(function(){
    // ここに実行処理を記述します
}, 2000); // 2秒後に1回実行

// くり返し行う処理
setInterval(function(){
    // ここに実行処理を記述します
}, 20000); // 20秒毎に実行
```
# Tampermonkeyに入れる実際のソース

今回、「楽天 ラッキーくじ」を自動化するために作ったのが、下記の2つのスクリプトです。

1. 楽天ラッキーくじ一覧 から 各くじリンクを開く
1. 楽天ラッキーくじを引く

「ページ内の要素の取得」、「一度のみ行う処理」、「くり返し行う処理」をJavaScriptで組み合わせただけで、特別難しいことはやっていません。

これらの2つのスクリプトをTampermonkeyに追加します。Tampermonkeyの詳しい使い方については、様々な解説ページがありますので、ここでは省略します。

## 1. 楽天ラッキーくじ一覧 から 各くじリンクを開く スクリプト

[楽天ラッキーくじ一覧](https://rakucoin.appspot.com/rakuten/kuji/)（非公式）から、楽天くじの各ページリンクを順番（20秒毎）に開きます。今回は「PC版ラッキーくじ」のみに限定しています。

```javascript
// ==UserScript==
// @name         楽天ラッキーくじ一覧 から 各くじリンクを開く
// @namespace    https://qiita.com/QDM
// @version      0.1
// @description  楽天ラッキーくじ一覧 の 各くじページリンクを順番に開きます。
// @author       QDM
// @match        https://rakucoin.appspot.com/rakuten/kuji/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var linkno = 0;
    var kujiPC = [];
    var kujiSP = [];
    var kujiOther = [];

    // 楽天くじのリンクリストを取得して配列にまとめる
    setTimeout(function(){

        var linklist = document.querySelectorAll('table[class="table"]');
        console.log("linklist: " + linklist.length);

        kujiPC = linklist[0].querySelectorAll('a');
        kujiSP = linklist[1].querySelectorAll('a');
        kujiOther = linklist[2].querySelectorAll('a');

        console.log("KujiPC: " + kujiPC.length);

        // 各くじのリンク情報を配列にまとめる(URLリスト確認用)
        var kujilist;
        for( var i=0; i < kujiPC.length; i++) {
            kujilist += kujiPC[i].getAttribute("href") + "\n";
        }
        console.log(kujilist);

    }, 2000);

    // くじのリンクを順番に開く(20秒毎)
    // 楽天くじを引く時間と、サーバへの負荷を考慮し、20秒毎に設定しています。
    setInterval(function(){

        if ( (linkno >= 0) && (linkno < kujiPC.length)){
            console.log("no:" + linkno);
            console.log("PC href: " + kujiPC[linkno].getAttribute("href"));
            window.open(kujiPC[linkno].getAttribute("href"));
        }
        linkno++;

    }, 20000);

})();
```

## 2. 楽天ラッキーくじを引く スクリプト

楽天ラッキーくじを引くためのスクリプトです。くじが、ハズレまたはくじ引き済みURLの場合、開いたページのタブを閉じます。

```javascript
// ==UserScript==
// @name         楽天ラッキーくじを引く
// @namespace    https://qiita.com/QDM
// @version      0.1
// @description  楽天ラッキーくじ 各ページ毎にくじを引きます。ハズレ｜くじ引き済み の場合、開いたページのタブを閉じます。
// @author       QDM
// @match        https://kuji.rakuten.co.jp/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // くじを引く
    setTimeout(function(){
        var locationurl = location.href;
        console.log("locationurl: " + locationurl);

        // https://kuji.rakuten.co.jp/******** などのラッキーくじURLかをチェックする
        var pattern = /https?:\/\/kuji.rakuten.co.jp\/[0-9a-zA-Z\/\?=_]+$/;

        if(locationurl.match(pattern) !== null){
            var btnStart = document.getElementById("entry");
            console.log("btnStart: " + btnStart.length);
            btnStart.click(); // くじを引く
        }
    }, 4000);

    // URLを確認して、ハズレ｜くじ引き済み の場合、タブを閉じる
    setTimeout(function(){
        var locationurl = location.href;
        console.log("locationurl: " + locationurl);

        var pattern = '/lose'; // ハズレ // URL後方一致
        if((locationurl.lastIndexOf(pattern)+pattern.length===locationurl.length)&&(pattern.length<=locationurl.length)){
            window.open('about:blank','_self').close(); // '_self'のclose()は、Chromeのみ動く
        }

        pattern = '/already'; // くじ引き済み // URL後方一致
        if((locationurl.lastIndexOf(pattern)+pattern.length===locationurl.length)&&(pattern.length<=locationurl.length)){
            window.open('about:blank','_self').close(); // '_self'のclose()は、Chromeのみ動く
        }
    }, 3000);

})();
```

#実行方法

Tampermonkeyに2つのスクリプトを入れたら、実際に楽天くじを実行してみます。

1. [楽天市場](https://www.rakuten.co.jp/)のログインから、ご自身の楽天アカウントで**事前に手動でログイン**します。
2. 楽天にログインが出来たら、[楽天ラッキーくじ一覧](https://rakucoin.appspot.com/rakuten/kuji/)（非公式）ページをChromeブラウザで開きます。
3. 無事Tampermonkeyのスクリプトが実行されていれば、あとは20秒ごとに、楽天くじの各リンクが新規タブで開き、自動的にくじを引いていきます。Tampermonkeyの実行状況は、ChromeデベロッパーツールのConsoleからログを確認します。
4. ハズレまたはくじ引き済みの場合、スクリプトが自動的にタブを閉じます。当たったくじのタブ、他ページへリダイレクトされるページは、開いたままになります。

- 通常の楽天くじとは異なるくじ形式(楽天IDとは別途ログインが必要なページ、特定の画面遷移を伴うなど)の場合、自動的にくじを引けないことがあるので、必要に応じて**手動**で対応するか、**諦めて無視**します（汗。
- くじ数 x 20秒かかるので、40個のくじがある場合、13分～14分ほどかかります。

##注意事項
- 楽天ラッキーくじの仕様変更や終了などにより、本記事のスクリプトが動作しなくなる場合があります。
- PCやネットワーク環境などにより、スクリプトが上手く動作しない場合があります。

#当選結果

当選結果は、後日ここで発表予定です。もしかしたら、1ポイントも当たらないかもしれませんが、とりあえず12月25日まで毎日やってみます。

楽天サンタさんが、高額ポイントをプレゼントしてくれたら嬉しいなぁ :santa:

|日付 |くじ引き回数 |当選回数:tada: |当選ポイント:moneybag: |
|:-----------------|:------------------:|:------------------:|:------------------:|
|12/10 |33 |0 |0 |
|12/11 |34 |2 |11 |
|12/12 |32 |2 |2 |
|12/13 |32 |1 |1 |
|12/14 |33 |0 |0 |
|12/15 |33 |1 |10 |
|12/16 |34 |0 |0 |
|12/17 |35 |2 |2 |
|12/18 |36 |1 |1 |
|12/19 |36 |0 |0 |
|12/20 |36 |4 |23 |
|12/21 |36 |0 |0 |
|12/22 |36 |0 |0 |
|12/23 |35 |3 |12 |
|12/24 |32 |2 |2 |
|12/25 |32 |3 |12 |
|合計 |545 |21 |76 |

当選確率: 3.85%（25.95回に1回）

期間限定くじを追加したことで、昨年（当選確率: 2.27%）より当選確率が向上しました。実のところ、スマホ版くじの方が、PC版よりも当選確率が高いようです。合わせてくじを引けば、当選確率５％くらいになるかもしれません。