将棋ウォーズの棋譜を取ってくる
あけましておめでとうございます。 2020年の目標は12月まで生存することです。 よろしくお願いいたします。
さて、2020年1月16日にスタイリッシュ・タップ・アクションゲームこと将棋ウォーズのアップデートがありました。
アップデートにより観戦画面の見た目が変わり、 「ぴよ将棋」等でURLを指定した棋譜の取り込みができなくなってしまいました。 これでは日々の対局の振り返りを手軽に行えず、非常に困ります。
そこで、対局URLから棋譜を取り出す自分専用botを作りました。
本記事は、ネットの情報を寄せ集めただけのポエム的な生存報告です。 技術的な詳細を知りたい方は参考にしたリンク先を御覧ください。
概要
今回作ったシステムのデータの流れを雑に示すと以下のようになります。
LINE botに棋譜URLを投げるとサーバ上でpythonスクリプトが走って、棋譜が返ってきます。
LINE bot
下記のサイトを丸パクリ参考にして、まずはLINEに投げた文章をそのまま返すbotを作りました。
Python + HerokuでLINE BOTを作ってみた - Qiita
ほぼ参考サイトの通りにコマンドを打ち込むだけでbotの動作までたどり着きました。
棋譜のパース
観戦URLで取ってきたhtmlには CSA形式っぽいjsonが埋め込まれています。 このjsonから必要なデータを取り出すことで棋譜データを作れます。
import requests import json from bs4 import BeautifulSoup INIT_BOARD = """\ P1-KY-KE-GI-KI-OU-KI-GI-KE-KY P2 * -HI * * * * * -KA * P3-FU-FU-FU-FU-FU-FU-FU-FU-FU P4 * * * * * * * * * P5 * * * * * * * * * P6 * * * * * * * * * P7+FU+FU+FU+FU+FU+FU+FU+FU+FU P8 * +KA * * * * * +HI * P9+KY+KE+GI+KI+OU+KI+GI+KE+KY""" def decode(url): res = requests.get(url) soup = BeautifulSoup(res.text, "html.parser") data = soup.find("div", attrs={"data-react-class": "games/Show"}) game = json.loads(data["data-react-props"])["gameHash"] csatexts = ["V2.2"] csatexts.append("N+{}".format(game["sente"])) csatexts.append("N-{}".format(game["gote"])) csatexts.append("$EVENT:{}".format(game["name"])) csatexts.append(INIT_BOARD) csatexts.append("+") t = [180, 180] for i, move in enumerate(game["moves"]): csatexts.append(move["m"]) elapsed = t[i % 2] - move["t"] t[i % 2] = move["t"] csatexts.append("T{}".format(elapsed)) return "\n".join(csatexts)
上で作ったオウム返しbotを少し書き換えて、観戦URLをスクレイピングしてCSA形式に変換するスクリプトを書きました。
完成品
難しいところがほとんどないため説明をすっ飛ばしましたが、最終的に以下のようなbotができました。