続・将棋ウォーズの棋譜をまとめて保存する方法
以前、将棋ウォーズの棋譜を 将棋ウォーズ棋譜検索β で検索してローカルに保存 という流れをやってみたが、 よく見たら2018年8月以降の棋譜が出てこなくなっていた。(私だけ?)
ということで、最近の棋譜を取得するべく、別の手法で棋譜をダウンロードしてみたいと思う。
さらに今回は、ローカルに保存するだけではなく、ローカルのデータベースに保存して棋譜を再生できるようにしてみた。 その際に必要となったセットアップなどのメモ。
成果物
データベースに棋譜を登録
最近のアップデートで戦型のタグがつくようになった。棋譜を解析しなくてもどういった内容かわかるのでとても嬉しい。
一応再生できる(必要性はない)
使用したコードは GitHub に公開している。
環境
- macOS 10.14
- anaconda3-5.0.0
- MongoDB 4.0.3
棋譜のダウンロード
基本的な方針は前回とほぼ変わらないが、今回は公式のサイトから収集する。
https://shogiwars.heroz.jp/users/history/ユーザーID/web_app?locale=ja
アクセスすると分かるが、対局履歴を一ヶ月分(?)くらい閲覧することができる。
このページから棋譜のURLを取得してく。具体的にはgame_replay
クラスの中にあるa
タグにリンクが貼ってある。
特定のページにアクセスしたい時は以下のようなパラメータを設定する。
params = { "page" : ページ番号(一番最初のページは page = 1) "gtype" : 対局ルール(3切れは"sb"、10秒将棋は"s1") }
とりあえずデータベースに登録したい時は GitHubにコードを公開しているので、
- コードをダウンロード
- 以下の手順でスクリプトを実行する
$ python updateDB.py
これでMongoDBに棋譜データが閲覧できる分だけ保存される。重複して登録しないようにしてあるので、後からもう一度実行することで新しい分だけを取得できる。
対局ルールは以下の規則で命名してある。
10分切れ負け | 10m |
3分切れ負け | 3m |
10秒将棋 | 10s |
もしデータベースじゃなくてローカルにファイルとして保存したいときは、
- コードをダウンロード
- 以下の手順でスクリプトを実行する
$ python downloadKifu.py
とすれば良い。
データベースを利用する準備
MongoDB のインストール
MongoDB というオープンソースのデータベースを使ってみる。
MongoDB はJSON形式でデータを格納できるので使い勝手が良い(個人的に)
- homebrew を使ってインストール
$ brew install mongodb
- mongodb の起動
$ brew services start mongodb
- 起動しているかどうかの確認
$ brew services list
- mongodb の停止
$ brew services stop mongodb
- 特定のコレクションに含まれているデータを全て表示する
$ mongo > show dbs > use [db name] > show collections > db.[collection name].find()
コマンド | 操作 |
---|---|
mongo |
mongoDB のシェルを起動 |
show dbs |
データベース一覧を表示 |
use [name] |
使用するデータベースを変更 |
show collections |
コレクション一覧を表示 |
db.test_collection.find() |
コレクションに登録されている内容を全て表示 |
pymongo のインストール
今回はPython 経由でデータを追加・参照する予定なので、PyMongoというライブラリをインストールする。
- pip を使ってインストール
pip install pymongodb
- mongoDBへのアクセス
>>> from pymongo import MongoClient >>> client = MongoClient("localhost", 27017)
- データベースを使用(なければ作成)
>>> db = client["db_name"]
- コレクションを使用(なければ作成)
>>> collection = db["collection_name"]
- コレクションに追加
>>> type(post) <class 'dict'> >>> collection.insert_one(post)
複数追加したい場合は,辞書のリストを作成し,
>>> type(post) <class 'list'> >>> collection.insert_many(post)
- コレクションを参照
全て取ってくる
>>> collection.find()
Cursor
というイテレータオブジェクトが返ってくる.
for文などで回すことで一つずつ参照できる.
一つ取ってくる
>>> collection.find_one({"key": "000"})
引数として渡した条件に一致するデータが返ってくる。
上での例でいうと、"key" が "000" のデータで一番最初に見つかったやつが返ってくる。
棋譜を再生する
Python の将棋ライブラリとしてpython-shogiがある。
とても使いやすいのでこちらを使って棋譜を再生してみた。
使い方
- pip を使ってインストール
$ pip install python-shogi
- 将棋盤を描画するまで
ポイント
入出力はSFEN形式で行う.
http://ch.nicovideo.jp/kifuwarabe/blomaga/ar795371
- 駒を動かす
>>> board.push(shogi.Move.from_usi(["操作"]))
- 盤面を描画する
>>> print(board.kif_str()))
- SFEN形式の文字列を取得
>>> board.sfen()
Tips
過度なアクセスはサーバーに負荷をかけるので十分に注意しよう。 少なくとも1秒くらい間隔を開けながらアクセスする!