teriyaki note

好きなものはラーメンと将棋

将棋ウォーズの棋譜をまとめてローカルに保存する方法

続編は以下の記事。

teriyaki398.hatenablog.com

後から調べたら...

すでに有識者がフリーウェアを開発してくださっていたので、
Mac でもやりたいよという人限定の話になってしまった

将棋ウォーズ棋譜ダウンローダー Wiki - OSDN

成果物

棋譜をダウンロードするPython スクリプトを作成し、一括DLできた!

f:id:teriyaki398:20180928100838j:plain

環境

Webスクレイピングの準備

selenium

今回は 将棋ウォーズ棋譜検索β で検索した結果を一括でダウンロードする方針でいく

このようにWebサイトから情報を一括でダウンロードすることを Webスクレイピングと呼び、
プログラムからブラウザを操作したいときには、selenium というソフトが使われる

今回はPython から操作したいので 以下のコマンドでパッケージを入れておく

% pip install selenium

ブラウザ

今回は Google Chrome をヘッドレスモードで使う。

ヘッドレスとは、実際にブラウザを起動して画面を描画したりしないモードと捉えておけば問題ないだろう

webスクレイピングは大量のデータにアクセスしたいので、いちいち画面を描画させると重くなってしまうのだ
(有名なヘッドレスブラウザとしてPhantomJS があったが、開発が終了してしまった)

selenium からブラウザを操作するためには、操作したいブラウザに対応するドライバが必要なので、以下からダウンロードしておく

Downloads - ChromeDriver - WebDriver for Chrome

具体的なコード

from selenium import webdriver
from bs4 import BeautifulSoup
import requests
from tqdm import tqdm
from time import sleep

# 操作するブラウザの準備
option = webdriver.ChromeOptions()
option.add_argument('--headless')
driver = webdriver.Chrome(executable_path='./chromedriver', options=option)

url = 'http://swks.sakura.ne.jp/wars/kifusearch/'
u_name = '取得したいユーザ名'

sleep(1)
driver.get(url)

driver.find_element_by_id('id_name1').send_keys(u_name)
driver.find_element_by_id('searchBtn').click()

# ページのソースを取得
soup = BeautifulSoup(driver.page_source, 'lxml')
driver.quit()

lis = soup.find_all(class_='btn1')
kif = []

for i in lis:
    if 'kif' in i.get('href'):
        kif.append(i.get('href'))

kif = ['http://swks.sakura.ne.jp/wars' + x[2:] for x in kif]

for i in tqdm(kif):
    sleep(1)
    r = requests.get(i)
    r.encoding = 'Shift_JIS'

    f_name = i.split('/')[-1]
    # ユーザ名のディレクトリ以下にファイルを保存するようにしている
    # あらかじめディレクトリを作成しておく
    with open(u_name + '/' + f_name, mode='w') as f:
        f.write(r.text)

流れは以下の通り

  1. selenium + Chrome で ID を検索する
  2. 検索結果のソースを取得
  3. 保存ボタンに棋譜のリンクが貼ってあるので、それを取得してリスト化
  4. GETリクエストを送り、棋譜を保存

Tips

実際のwebページがどのように記述されているかによってコードが変わるので、
Chrome の場合)右クリック -> 検証 からコードを表示しながらプログラムすることになる

今回の場合、検索ボックスに 属性id_name1、検索ボタンに属性searchBtn が付与されていたので、 それらを検索し、文字列を入力 > 検索 という流れで結果を取得した

また、今回は 10分切れ負けに絞ったが、もし他の対局ルールでの棋譜が欲しい場合は
ラジオボタンを選択する処理が必要となる

取得した棋譜ファイルを活用して、例えば 四間飛車 vs 居飛車穴熊 だけ抽出
といったことができるだろう