Google スプレッドシートで定期更新ゲームのデータを自動的に取ってくる
この記事は定期ゲやったことある人たちのアドカレ Advent Calendar 2020(通称わたカレ)の7日目の記事です。
(もうみずわたさんが記事書いてくれたし、このアドベントカレンダーの最終目標は達成されたのでは…?まあいっか)
さて、こんにちは。herietです。定期更新ゲーム自体はまったりと遊ばせてもらっています。定期更新ゲームについては自分のキャラクターをつくりあげていくのがメインの楽しみ方ではありますが、おまけでツールを作るのも楽しかったりもします。過去には超鳥瞰図とかてごねスキルストーンとか他にもいろいろ作ったりもしていました。
定期更新ゲームとツール
定期更新ゲームにおいて、情報収集と整理がとても大事な要素です。定期更新という言葉が示すとおり、その核にあるのは定期的に更新される更新結果です。そして、その更新結果というものは膨大な情報量になります。そのすべての更新結果を、じっくり閲覧するほど人類の可処分時間は与えられないわけで、泣く泣くある程度絞って更新結果読まなければいけないわけです。
そんなとき活躍するのが更新結果のデータを収集して整理してくれるツールです。たとえば、騒乱イバラシティにおける荊街データ小屋のようなものですね。公開されているツール以外にも自前でプログラムを組んで結果を収集されているかたもいることでしょう。定期更新ゲームというゲームが、Web上のHTMLとして出力される以上、その結果の収集や整理にはプログラムを書いてツールに仕立てることが非常に効果的です。
定期更新ゲームというジャンルそのものが、運営側で出力される更新結果だけではなく、プレイヤーが各自で作成したツールを前提として成り立ってる面があるのも面白いなと思うところです。ツールがあるからこそ、キャラクターのロールプレイングに費やす時間により注力できるという側面もあります。運営側で必要となるツールを提供できればよりいいのかもしれませんが、個人運営の定期更新ゲームが多い現状、そこまではなかなか整備できないという事情も大きいでしょう。ツールだけではなく、有志が作成しているWikiなどもそうですね。昨今はデータをまとめるためのツールやWikiがより発展しており、おかげで定期更新ゲームがより遊びやすくなったな感じているところです。
一方で、ツールを作るためにはやや特殊なスキルセットが必要です。キャラクターではなく、プレイヤーのスキルですね。特殊といっても特段難しいわけではなく、HTMLの知識と簡単なプログラミングの知識、あとはツールの作り方をググる知識があればだいたいなんとかなります。とはいえ、定期更新ゲーム全体のユーザーの母数からすると、その中でツールが作れる人というのはやはりマイナーな部類になるでしょう。
定期更新ゲームをやっている中で、プログラミングは全然わからんけど、こういったツールがあったら便利なのになぁ…みたいなこともしばしばあるのではと思います。というわけで、今回はプログラミングの知識がほとんどなくても実現できる、Google スプレッドシートをつかった情報抽出ツールの作り方を紹介したいと思います。
Google スプレッドシートとは
Google スプレッドシートはGoogle謹製のブラウザで操作できるスプレッドシートです。表計算ツールみたいなことができるものですね。Googleのアカウントさえあれば、誰でも無料で使うことができます。
スプレッドシートのリンクを貼れば簡単に他者に共有できますし、同時編集ができたり、権限を絞ってチームメンバーにのみ情報共有したりとなにかと便利なツールです。
すでに定期更新ゲームのデータ整理などの用途で使われている方も多いのではないかなと思います。データ整理のためだけでもとっても便利なGoogle スプレッドシートですが、なんと定期更新ゲームの更新結果から自動でデータを取ってくる事ができます。更新結果などのWeb上のものから自動でデータをとってくることを、スクレイピングとも言いますね。
GoogleスプレッドシートでENoからキャラクター名を取得する
今回は絶賛稼働中の騒乱イバラシティを例にとって、スクレイピングをやってみたいと思います。まず、一番簡単な例として、ENoからキャラクター名を取得する方法を紹介します。
とりあえず、今回取得したいENoをスプレッドシートに記入します。今回は1424とします。ENoがわかれば、そのキャラクターのURLは簡単に生成できますね。URLの列(B2)には下記のように入力します。
="http://lisge.com/ib/k/now/r" & A2 & ".html"
ついでに、イバラシティでは上記URLのnowのところに更新回の数字を入れれば、過去結果のURLにもなりますね。今回はnow固定にしますが、更新回のような列があってもいいでしょう。
さて、ENoとENoから生成したURLがスプレッドシート上のデータとして入力されました。この状態から、C3セルにキャラクター名を取得したいです。そのためには、 IMPORTXML関数を使います。C3セルに下記を入力してみましょう。
=IMPORTXML($B2, "//title")
はい。キャラクター名が取得できましたね。(厳密には [1424] の部分はキャラクター名ではありませんが、今回はいいことにします)
IMPORTXML関数の解説を簡単にすると、1つ目の引数はデータを取得したいURLです。今回はB2セルのURLですね。そして2つ目の引数(今回は "//title")は XPathと呼ばれるもので、URL先のHTML(またはXML)におけるデータの場所を表現する文字列です。今回はHTMLでいうところの titleタグ内の値です。イバラシティではキャラクターページのtitleタグがキャラクター名になっているので、このようなデータが取得できたわけです。
さて、つまりこのIMPORTXMLを使い、XPathを取得したいデータの場所さえ指定できれば、Googleスプレッドシート上にすべてデータとすることができます。すごいですね!
…えっ?XPathの設定の方法がわからない?そうですね。XPathについては前提としてHTMLの知識も必要で、少しハードルが高いと思います。そこで、XPathがよくわからなくても、XPathを簡単に取得できる方法を2つ紹介したいと思います。
ChromeでXPathを取得する
今度はキャラクターのMHPを取得してみましょう。MHPのXPathさえわかれば、同じ方法でスプレッドシートに読み込むことができます。
今回はChromeを使ってXPathを取得してみます。まず、対象の画面を開いた状態で「F12」を押して(もしくはメニューから「表示」>「開発 / 管理」>「デベロッパー ツール」から)デベロッパーツールを開きます。
デベロッパーツールの「Elements」タブ左端の矢印を選択したあと、対象の要素(今回はMHPの値)をクリックすると、下画面でそのHTML要素の位置に移動します。そのHTML要素を右クリックして、「Copy」>「Copy XPath」を押すと、その要素のXPathを得ることができます(下画像参照)
上記の操作を行ったあと、クリップボードにXPathのデータが入っているはずです。今回は 「/html/body/div/div[2]/div[10]/div[16]/div[1]」というXPathが得られました。これをキャラクター名のときと同様にIMPORTXMLの引数にしてみます。
無事、MHPの値がスプレッド上に読み込まれましたね。
さて、大抵の場合はこの方法で問題がないのですが、イバラシティにおいてはこの方法は通用しないことが多いです。他のENoで試してみるとわかるのですが、キャラクターによってこの方法で取得したMHPのXPathの内容が変わってしまいます。つまり、同じXPathが使い回せません。キャラクターによって、HTMLの構造が変わってしまうためにこの問題が発生します。(もしくは、対象のHTML構造が汚いせいだったりもする)
ChromeのRuto拡張機能でXPathを取得する
XPathの知識があればよりよいXPathにすることは可能なのですが、それを補填する拡張機能が存在します。今回はChromeのRutoという拡張機能を使います。
Rutoをインストール後Chromeを再起動し、拡張機能のメニューから下記のように操作します。
Rutoにより、いくつかのXPath候補が提示されます。候補は複数出てくるので、XPathがわからない場合でも、実際に試してみれば問題がないかはすぐわかるでしょう。今までと同様に、IMPORTXMLのXPathとして与えます。
より複雑なXPath
上で紹介した方法で、多くの要素は適切なXPathが取得できるはずです。ただし、やはり単純にはできない場合も多くあります。対象のHTML構造が汚いと特に難しくなります。
たとえば、イバラシティのキャラクターページから1つめのアイテム名を取得したいとなったときのXPathの例としては「"//div[@class='Y870']//table/tbody[1]/tr[1]/td[text()='No']/../../tr[2]/td[2]"」となります。この複雑なXPathはRutoでも得ることはできません。人力でHTML構造を読み、XPath構文を理解した上で書く必要があります。この辺は難しくなってしまうので、ちゃんと勉強するか、あきらめるしかないでしょう。
複雑なXPathを書かなくても済むように、定期更新ゲームを開発する側の皆様におかれましては、id属性を適切に付与するなど、なるべく綺麗なHTMLを出力していただけると大変うれしいです。もしくは更新結果と同等な情報をjsonあたりで吐いてくれるともっと嬉しいですね。
Google スプレッドシートの注意点
Google スプレッドシートでは、IMPORTXMLによるデータ取得時、Google側でキャッシュしたデータが使われています。毎回そのサイトにアクセスしにいくと、負荷になってしまうからですね。
自動的にキャッシュしてくれてありがたいのですが、このキャッシュは仕様上1時間ほど保たれるようです。つまり、一度データを取得したあと、同一ページに更新があっても1時間は待つ必要があります。つまり、定期更新ゲームの更新直後ではキャッシュが効いて古いデータを参照してしまうことがあるはずです。これを回避するにはいくつか方法はありますが、おとなしく1時間待つか、Googleスプレッドシートではなくやはり自分でプログラムを書く方がよいでしょう。
まとめ
Google スプレッドシートで自動的に定期更新ゲームのデータを取ってくる方法を紹介しました。データさえ取得できれば、スプレッドシート内でいい感じに加工したりまとめたりすることも簡単にできて便利ですね。
自前でプログラムを書く方法に比べると自由度には劣るのですが、プログラミングの知識がなくても簡単にできますし、わりと多くのケースには対応できるのではと思います。なお、今回は紹介しませんでしたがOctoparseのようなプログラミング不要なスクレイピングツールなんかも最近はたくさんあるのでそういうのを試してみてもいいかもしれません。
そんなわけで、自分で必要なツールを作ることもまた定期更新ゲームを楽しむ一つの楽しみ方だったりします。ついでに定期更新ゲームの情報収集をより便利にすることもできます。是非お試しあれ。