mechanize を用いたギタドラのスキルポイント記録システム(2)

KONAMIへのログインに画像の認証が必要になっちゃったので以下の方法はのちのち改良します。

前回までのあらすじ

ギタドラスキルポイント推移を自動で記録したい!
Ruby の mechanize と Nokogiri を使うんだ
・よーし
・だいたいの方針

  1. e-amusement GATE へログイン
  2. ギターおよびドラムのスキルポイント・全スキルポイントを切り出す
  3. 直近のスキルポイント・全スキルポイントと比較する
  4. スキルポイント・全スキルポイントの変化のしかたで場合分けし、必要な場合は最終プレー日時を取得する
  5. 保存方法(保存しないパターンも含め4種類)のどれかで処理する
  6. (cron で1日1回自動更新する)

はてさて、今回はどうなることやら……

スキルポイントについて

ギタドラで遊べる数百曲について、各曲のスキルを合計したものが全曲スキルポイント
全曲のうち、高いものから50曲ぶんのスキル値を合計したものがスキルポイント。(この値でその人の腕前がわかる)
ようするに昨日よりうまくなっていれば上がります。そうでなければ上がりません。*1

スキルポイントを取得してみる

とりあえず、実際にログインしてスキルポイントを切り出してみる

agent = Mechanize.new
agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
agent.get(ログイン画面のURL)
agent.page.encoding = "utf-8"
form = agent.page.forms.first
form.field("KID").value = コナミID
form.field("pass").value = パスワード
agent.submit(form, form.buttons.first)

これでログイン完了。証明書無視しちゃってるけどとりあえずはOKってことで。

page = agent.get(スキルポイントが書いてあるページのURL)
agent.page.encoding = "Shift-JIS"

puts page.search('td')[1].text.to_f
puts page.search('td')[2].text.to_f
puts page.search('td')[4].text.to_f
puts page.search('td')[5].text.to_f

で、

取れた!

場合分けのお時間

直近のスキルポイント (GF/DM/GF全/DM全) と、 最新のスキルポイント (GF/DM/GF全/DM全) を比較するとなると、全部で16パターンあった。

からの

こうである。(playG, playD は ギターフリークス/ドラムマニア をプレーしたかどうか)
全曲スキルポイントが上がった、ということはその日その機種をプレーしていることがわかる。ここに着目して、上図では16パターンを大きく4つに分けている。

  • (A)両方上昇
  • (B)GFだけ上昇
  • (C)DMだけ上昇
  • (D)両方変化なし

の4種類である。まずこの4種類のどれかに当てはまり、そして (B)〜(D) の場合は最終プレー日時をチェックして、その日ゲームをプレーしてるかをはっきりさせる。GF も DM もプレーしていなければ、その日は記録を行わない。

方針をすこし変更

さて16パターン中、最終プレー日時を調べる必要があるのは12パターンであることがわかった。だいたい4分の3で調べにいく必要があるのである。
だったら“必要に応じて”より、毎回やることにしちゃったほうがすっきりしそう……ということで、基本的に最終プレー日時を取得しにいくことにした。また、スキルポイントを記録していくファイル (output.txt) とは別に、動作結果を出力しておくファイル (log.txt) をつくることにした。柔軟な姿勢だ。

結局のところ

  1. e-amusement GATE へのログイン
  2. 最新のスキルポイント・全スキルポイントおよび最終プレー日時を取得
  3. 直近のスキルポイント・全スキルポイントを読みだす
  4. 各ポイントおよび日付の比較を行う
  5. スキルポイントの変化のしかたに応じて場合分けし、実行日に両機種をプレーしているかどうかはっきりさせる
  6. ファイルヘ保存 (もしくは保存しない)

という感じの流れになった。

書いたのがこちら。
https://gist.github.com/yamatema/b1f54793e02a303f7c79

cron の設定は
crontab - cron で ruby を自動実行する - Qiita http://qiita.com/tkwn1/items/204ebfaffa3bad9e2a99 を参考に、毎晩23時55分に実行されるように設定。つまり23時半くらいにはゲーセンを出ろってことになる。

出力のようすがこちら。上が output.txt、 下が log.txt。


ゲーセンいってねえな!

今後やりたいこと

・実行結果を twitter に流す
・今後、曲の削除が起こったときにスキルポイントが下がるのでちゃんと対応したい
・証明書どうすんだ

・文章がギッタンギッタンなのでもう少し整理すればよかった


◇いじょうです◇

mechanize を用いたギタドラのスキルポイント記録システム(1)

あけましておめでとう

去年の年末にせっかくVPSをけいやくしたのに、fav通知にしか使ってないってのは何とももったいないよナー……
と思っていたのだけど、僕は前々から音ゲーム GITADORA GuitarFreaks&DrumManiaスキルポイント (簡単にいうと、やりこみ具合を計る数値で、むつかしい曲ほど、高得点ほど高い数値を得られる) を Excel ファイルにちょこちょこ記録する習慣があったのでした。ゲームセンターで GITADORA をプレーした日は欠かさず公式サイトでポイントをチェックして記録、チェックして記録……を繰り返していたわけです。

しかしそうは言っても、毎日行ってるわけでもなし、忘れちゃうときもあります。実際やってみると5分もかからない作業なんだけど、正直ちょっと面倒だなとも感じていたところ……
友人 @kyubing に『Ruby の mechanize と Nokogiri という Gem を使うと、インターネットの各種ページから必要な情報だけ切り取ってくることができるよ』と教えてもらい、「なるほどそれを使えば自動化できちゃえそう」と思い立ち、今回の活動が開始したのでした。

Rubyの経験はおありですか

おありなんですけど、修士論文書いてたころの方が知ってたと思う……ってくらい書けなくなっていた。ひどい。
ということで『たのしいRuby』の第4版を Kindle にぶちこんで、色々あちこちで復習しつつ書いていくのでした。
@kyubing の書いた jubeat (別の音ゲーム) についてのスコア集計 (とアップロードの) スクリプト*1や、mechanize 及び Nokogiri の基本的な使い方解説*2 *3 *4などを読みあさり色々試作してみて、とりあえず http://yamatema.com から自在にテキストを切り出すところまではできるようになったのでした (cssにちゃんと触れたのは今回が初めてだったよ)。

先駆者を見つける

mechanize というやつは人間の代わりにリンクをクリックしてくれたり、フォームのボタンを押してくれたりするニクい奴で、つまりは KONAMIe-amusement GATE (公式サイト) へのログインもしてくれるわけである。べんり。
さてフォームについてはどう書けばいいんだ……調べていたら、DDR で同じことを既にやっている人がいた*5のを発見したのでした。ログイン部分をまるまる使わせてもらってしまった。SSL証明書についてはまたあとでちゃんとやる。

あとは自力でやっていく

僕はこういうことを考える際すぐ迷子になるので、大まかな流れを書きだして方針とし、そこから詳細を突いていきました。
そのときのようすがこちら。

!! ギタドラスキルポイントを自動で記録するシステム !!
・とりあえずの流れ
 1)e-amusement GATE へログイン
 2)ギターおよびドラムのスキルポイント・全スキルポイントを切り出す
 3)ファイルへ書き込む

・すこしくわしく
 * 切り出しは Ruby の Mechanize で行う
 * あとで Excel に叩き込むつもりなので CSV 形式で出力する

・おなやみ
 A)サーバーにうつして cron で1日1回自動で更新する
  A1)ポイント変化がなかったときも記録する
  A2)ポイント変化がなかったときは記録を行わない
 B)サーバーにうつして任意のタイミングで、手動にて更新する

更新しわすれを防ぐには(A)案がよさそう
 しかし(A1)案ではログが日ごともったりしていきそうな心配
  →1年毎日動かしても、せいぜい約360行のテキストファイルだし問題ない気もする
 (A1)及び(A2)案のどちらも「プレーしたけどスキルがあがらなかった日」が把握できない
  →(B)案ならばプレーした日に走らせる習慣をつければ把握できる
   →自動化したいんですけど!!!
    →はい

では(A2)と(B)を合わせてみる
 大半は自動になったが、やはり手動だと忘れる可能性が大きいし、全自動にしたい
 その為には(A)案の弱点である「プレーしたけどスキルポイントがあがらなかった日」をうまいこと定義しないといけない……
 弱点を「プレーした」「スキルポイントがあがらなかった」と分けると、「その日プレーしたかどうか」という情報が必要だとわかる。これをどこから入手するか……
 →『プレー履歴のページから、最後にプレーした日時を取得する』これだ!!!

ということで最終的に、

  1. e-amusement GATE へログイン
  2. ギターおよびドラムのスキルポイント・全スキルポイントを切り出す
  3. 直近のスキルポイント・全スキルポイントと比較する
  4. スキルポイント・全スキルポイントの変化のしかたで場合分けし、必要な場合は最終プレー日時を取得する
  5. 保存方法(保存しないパターンも含め4種類)のどれかで処理する
  6. (cron で1日1回自動更新する)

という感じになりました。

長くなりそうっていうか長いのでとりあえずここまで。

*1:https://gist.github.com/clicube/1336156

*2:Nokogiri の基本(翻訳版) - Engine Yard http://www.engineyard.co.jp/blog/2012/getting-started-with-nokogiri/

*3:Nokogiri を使った Rubyスクレイピング初心者向けチュートリアル - 酒と泪とRubyRailshttp://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/

*4:Mechanizeによるスクレイピングの基本的なことまとめ - そのねこが学ぶとき http://chroju89.hatenablog.jp/entry/2015/02/08/133507

*5:DDRで消費したカロリーを自動でツイートする (その3) http://shimazakky.hatenablog.jp/entry/2014/02/03/011424

Boxnya!

Boxcarを置き換えるふぁぼ通知システムでおなじみの Boxnya を導入しようと思ったら、twitterアカウント認証のところで長らくコケてた。

作者ののん氏に泣きついたところ、「時刻設定はちゃんとなされているか?」とのこと。
そ、そんなの知らない……

$ date

すると実際の時刻から30分くらい遅れてた。なるほど。
そして ここ を参考にするとよい、ってことで一通り従って時刻を正確にしてからもう一度認証を試みると成功。

デーモン化してほうってみる。

さくらVPSであそぶ

とりあえずさくらVPSに1年契約しました。

・初期設定はここを見てモリモリと。
http://www.xn--vps-073b3a72a.com/ :初心者でもわかる!さくらVPS - Sakura VPS マニュアル

FTPの設定は以下を参照しながらモコモコと。
http://pro-grammer.info/archives/902 :初心者プログラマー奮闘記 さくらのVPSを使ってみる【9】-vsftpdをインストールしてみる
http://plusblog.jp/6601/plusblog :さくらVPSFTPサーバー(vsftpd)を1時間で導入

ドメインValue-Domain で取得して設定
http://www.softantenna.com/wp/webservice/value-domain-and-sakura-vps/ :【2014年版】バリュードメインで取得したドメインを素直にさくらのVPSで使用する方法

・そして次はBoxnyaを

Nexus7でとりあえずProcessingを動かしたかった

Nexus7を入手したものの、Processingを動かすまでにウンウンいってた話。
結果として、WindowsXP 上で Processing 2.0b8 で書いて Nexus7(Android 4.3) で「とりあえず動く」ところまでいきました。Android エミュレータは動いてません。そのほかの場合どうなのかは知りません。

過去の自分と未来の誰かに向けて書きとめておきます。
(2013/8/30現在)


(A1) Android SDK のダウンロード
Android SDKここ からダウンロードする。
ADT Bundle版でOK。32bit版ならx86、64bit版ならx64をダウンロード・解凍後、インストーラを起動してお決まりの色々をこなす。その後インストールされた "SDK Manager" を起動する。

(A2) SDK をインストール
SDK Manager が起動したら、以下をインストールする。

あとついでに Android 4.3(API 18) の SDK Platform 及び Google APIs もインストールしちゃったけどたぶん関係ない。というかこの部分が割と適当で、API 7か8、もしくは10なら動くとのこと。なので全部乗せ。いささか乱暴。

ここまでは http://www.javadrive.jp/android/install/index1.html を見ながら進めました。



(P1) Processing のダウンロード
Processing IDEここ から頂いてくる。
当初は最新版の Processing2.0.2 で動かそうとしたものの、何やら機嫌が悪いらしいのでアップデート前の Processing2.0b8 で動かすことにした。ダウンロードページには過去のバージョンもちゃんとおいてある。はず。
ダウンロードしてきたら解凍して然るべきところに置いて、Processing を起動。

(P2) Android Mode のインストール
※Processing 2.0b8 なら既に Android Mode がインストールされてるのでここは飛ばしてしまってOKかも。この操作は2.0.2でなんとかしようとしてたときのものです。

起動した Processing のウィンドウ右上の [Java ▽] をクリック。
さらに [Add Mode...] をクリック。
Mode Manager が開くので、表示されている "Android Mode" を選んでインストールする。

ここで Android Mode が表示されなかった場合は Processing を再起動すると出てくるかも。

Android Mode のインストール中に "Is the Android SDK installed?" と訊かれる。
なので言う通りにさっきインストールした Android SDK がいる場所を指定してあげる。
(例: C:\androidUMAI\adt-bundle-windows-x86-20130729\sdk)

Android Mode のインストールが完了したら、ウィンドウ右上の [Java ▽] をクリックして "Android" を選べば Android Mode のはじまりはじまりだ。


(N0) Nexus7 の入手
(N1) Nexus7 の設定をいじる

設定メニュー>タブレット情報>ビルド番号 を 7回タップする。

Android 4.3 からはこの操作をしないと開発者向けオプションが表示されないようになったらしい。ぐぐるまでさっぱり分からずいちばん焦った。あの赤ら顔を何回見たことか。

設定メニュー>開発者向けオプション>USBデバッグ を有効にする。
設定メニュー>開発者向けオプション>スリープモードにしない を有効にする。
設定メニュー>セキュリティ>提供元不明のアプリ にチェックを入れる。

Processing との通信中に Nexus 7 がスリープしちゃうと面倒なことになりそうなので一応チェックをいれておくことにした。

(N2) Nexus7 の接続、ドライバ更新
Nexus7 備えつけのケーブルでUSB端子に接続する。
新しいハードウェアが云々言われるけどとりあえずキャンセルして、

システムのプロパティ>ハードウェア>デバイスマネージャ を起動

「その他のデバイス」に Nexus 7 が表示されているはずなので、プロパティを開いて全般タブからドライバの更新を行う。ここで Android SDKGoogle USB Driver があるディレクトリ (\sdk\extras\google\usb_driver) を参照させる。これでドライバ更新に必要な情報の書かれている usb_driver\android_winusb.inf が読みこまれ、Android Composite ADB Interface がインストールされる。
(N2)では ここ を参考にしていますが、Google USB Driver をインストールしたからなのか、android_winusb.inf には既に Nexus 7 のPIDとUIDが書かれていたので特に編集せずにドライバの更新を行ってしまっています。
☆★☆
これで準備はおわり。Android Mode の Processing でかんたんなスケッチを書いて(sizeは省くといい)、"Run in Device"ボタン(普段スケッチを実行するときに押しているボタン)を押すと、ややあった後に Nexus 7 で Processing が実行されている……はず。何かがおかしいと Processing のウィンドウで怒られる(だいたいの場合「デバイスが見つからない」と言われる、もしくはスケッチの文法がどこかおかしい)ので見直してなんとかしてください……
また、Run in Device を押すと、書いたスケッチが Nexus 7 に送られて残ります。サンプルスケッチをモリモリ動かすと Nexus 7 にモリモリたまっていくので適宜消すか、Javaモードでサンプルを動かすなどした方がよさそう。Android Emulator がちゃんと動いてくれれば心配ないんだけども……ウーン、少々後味が悪いのである……

(2013.09.05 追記)
なんかよくわからないけどAndroid2.0.2でも実機で動かすことができるようになってました。でもエミュレータは動かず。
☆★☆
ほかにも参考にしたのはここ
http://www2.kobe-u.ac.jp/~tnishida/course/2013/programming/android.htm

Rubyをけんきゅうに役立てたはなし

お研究でテキストファイルをわんさか扱っております。実験条件の指定(インプット)もテキストファイル、実験結果もテキストファイル。条件指定のファイルは基本的に同じ文面だけど一部数値をちょっとずつ変えていくもので、実験結果ファイルは……いろいろと書いてあるけど必要な部分はほんの少し、というもの。
最初は20個ずつだったファイル。インプット20個なら手入力でもなんとか……などと思っていたが実際面倒でしんどい。結果ファイルの方は「開く → Ctrl+F → みつける → 1行コピー → 表に貼り付け → 閉じる → 次のファイルを開く」のくりかえしでこっちが倍の倍しんどい。
これが40個ずつに増えて即座に嫌気が指した僕は「なんかRubyにファイルアクセスとかそういうのあったよなあ、インプットファイルを一気にもりもり作ってくれるのとか、結果ファイル読んでまとめてくれるの書けないかな……書けそうな気がしてきたぞ、ウオオ」と思い立ち席を立ち、研究室をあとにした。教授困惑。

色々試した結果、Fileクラスと正規表現を振りまわしてなんとか両方実現できました。インプットファイルの方はなんかもう本にサンプルあった気がするくらいのかんたんなコードでできた。一方の、結果を読んでまとめる方はかなり時間がかかることになったが、前回の友人のおかげで完成した。strip!とかsqueeze!とか使う。

自分の作ったものが自分の思った通りに動作するってすごく気持ちがいいのでこれからもRubyやりたい。

文字化けスレイヤー

twitterbotをつくろうとしているのだけど、コマンドプロンプトで文字化けが直らなくてこまっていた。
コマンドプロンプトはShiftJISでよみかきしてて、TwitterUTF-8でよみかきしてるから Kconv であれこれ試していたのだけれど、一向に直らない…もうだめだ!

と、友人の助言によりRubyのバージョンを1.8.7から1.9.3あげましたらスッキリと解決しました。前途多難です。