将棋ウォーズの棋譜をまとめてローカルに保存する方法
続編は以下の記事。
後から調べたら...
すでに有識者がフリーウェアを開発してくださっていたので、
Mac でもやりたいよという人限定の話になってしまった
成果物
棋譜をダウンロードするPython スクリプトを作成し、一括DLできた!
環境
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)
流れは以下の通り
Tips
実際のwebページがどのように記述されているかによってコードが変わるので、
(Chrome の場合)右クリック -> 検証 からコードを表示しながらプログラムすることになる
今回の場合、検索ボックスに 属性id_name1
、検索ボタンに属性searchBtn
が付与されていたので、
それらを検索し、文字列を入力 > 検索 という流れで結果を取得した
また、今回は 10分切れ負けに絞ったが、もし他の対局ルールでの棋譜が欲しい場合は
ラジオボタンを選択する処理が必要となる
raspberry piの初期設定
とりあえず自分が行った設定のメモ
基本的にSSH接続して、操作することを想定している
環境
- Raspberry Pi 3モデルB
- TOSHIBA SDHCカード 16GB Class10
Raspbian 起動以前
ラズパイの標準OSであるRaspbianをインストールする
イメージファイルを用意する
公式サイト
Raspberry Pi Downloads - Software for the Raspberry Pi
過去のバージョン
Index of /raspbian/images
SDカードをフォーマットする
windows10なら右クリック -> フォーマットでできる
専用のソフト(SDFormatterなど)を使ったらもっと分かりやすいかもしれない
Mac OSならディスクユーティリティを使って可能
Raspberry Pi 3にRaspbianをインストール(Mac OS X を使用) - Qiita
OSをSDカードに書き込む
Windows
Win32 Disk Imager が簡単か
Win32 Disk Imager download | SourceForge.net
Mac OS
Raspberry Pi 3 初期セットアップ(Mac 用) - Qiita
*df -h
でSDカードを確認(仮に/dev/disk2s1とする)
% sudo diskutil unmount /dev/disk2 % sudo dd bs=1m if=2017-01-11-raspbian-jessie-lite.zip of=/dev/rdisk2 % sudo diskutil eject /dev/disk2
Raspbian で直接やること
キーボード、マウスなしで最初からやれるらしいが、持ってるならそれでやって問題ない
Raspberry Pi モニタなしキーボードなしマウスなし パソコンのみでRaspberry Piのデスクトップにアクセスする。 - Qiita
インターネットに接続する
raspberry pi 3はwifiが使えるので楽ですね
ファイルシステムの最適化
大きな容量のSDカードを入れても正しく認識してくれなかったりするらしい
新しいバージョンだと大丈夫なこともあるらしいが、一応確認した方がいいかも
% df -h
を実行し、/dev/root
のサイズを確認する
このサイズがSDカードの容量とほぼ一致していればOK
もし小さく表示されているようなら以下を実行
% sudo raspi-config
から Expand Filesystemを選択
raspi-configからやること
- Change Password
- Interfacing Options - SSH
ここまでやったらあとはリモートから操作可能。
SSHでログインする
% ssh -p [ポート番号] pi@[IPアドレス]
アカウント名を変えている場合はpiの部分を変更する
ファイルの転送を行いたい場合は
% scp -P [ポート番号] [送りたいファイル] pi@[IPアドレス]:[送りたい場所(/home/pi/...)]
SSHのポート番号を変更する
% sudo apt-get install vim % cd /etc/ssh % sudo vim sshd_config
ここでPort 22
をコメントアウトし、他の番号に変更しておく
色々更新する
% sudo apt-get update % sudo apt-get upgrade % sudo apt-get dist-upgrade # ディストリビューションを最新に % sudo rpi-update # ファームウェアを最新に
Tpis
.bashrc
.bashrc
ファイルをカスタマイズすると快適になる。
alias ls='ls -F --color=auto' alias ll='ls -l -1'
を追加しておいた
友人の特定ツイートにクソリプを自動的に送りたい
(Python 2.7.13)
Twitter APIを使ってみたという記事は山ほどあるので、今更という感じだが
成果物
特定のユーザが"二郎"という単語を含んだツイートをすると、自動的に二郎に誘うリプを送る
(二郎:一部の人が大好きな高カロリーラーメン)
Twitter API の準備
これも多くの人が解説してくれてるので、そちらを参照しよう
Twitterアプリケーションの作成(Consumer key、Consumer secret、Access token、Access token secretの確認方法)
以下の4つの情報が取得できればOK * Consumer Key (API Key) * Consumer Secret (API Secret) * Access Token * Access Token Secret
Python ライブラリ
わざわざライブラリを使うまでもないとは思うが、圧倒的に楽なので
様々なライブラリが存在するが、今回はこちらを用いる
GitHub - sixohsix/twitter: Python Twitter API
以下のコマンドでインストールする
% pip install twitter
基本的には以下のような形で用いる
各認証情報は先ほど取得したものに置き換える
また、タイムラインなどは辞書型で取得される
from twitter import * # 認証情報 CONSUMER_KEY = "Consumer Key" CONSUMER_SECRET = "Consumer Secret" ACCESS_TOKEN = "Access Token" ACCESS_TOKEN_SECRET = "Access Token Secret" twitter = Twitter( auth=OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET) ) home_timeline = twitter.statuses.home_timeline() # ホームのタイムラインを取得(デフォルトは20件) user_timeline = twitter.statuses.user_timeline(screen_name="@xxxx") # 指定したユーザのタイムラインを取得 twitter.statuses.update(status="hello") # "hello" とつぶやく
指定できるパラメータの情報などはこの辺りで確認しよう
POST statuses/update — Twitter Developers
特定のツイートに対してリプをする
各ツイートにはid
が設定されており、ツイートの際にこのidを指定することで、特定のツイートにリプが返せる
ユーザ@xxxx のツイートid yyyyにリプするときは以下のようにする
status_id = "yyyy" twitter.statuses.update(status="@xxxx hello", in_reply_to_status_id=status_id)
基本的な流れは、
- ユーザのタイムラインを取得
- 取得したツイートのテキストにキーワードが含まれているかを判定
- リプ済IDリストを確認し、まだリプしていないならクソリプし、IDをリストに追加
- 1分ほど待って、1.に戻る
これを繰り返すことで、自動的にチェックしてリプする
同じツイートにリプを返さないように、一度リプしたものは除外する処理が必要
# coding:utf-8 from twitter import * import time # 認証情報 CONSUMER_KEY = "Consumer Key" CONSUMER_SECRET = "Consumer Secret" ACCESS_TOKEN = "Access Token" ACCESS_TOKEN_SECRET = "Access Token Secret" SCREEN_NAME = "@xxxx" twitter = Twitter(auth=OAuth(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET)) status_id_list = [] # 同じツイートにリプしないように、リプしたidを記録しておく while True: # secreen_nameのユーザのタイムラインを取得 tweet_list = twitter.statuses.user_timeline(screen_name=SCREEN_NAME) # 二郎に関するツイートをしていた場合、クソリプを送る for tweet in tweet_list: if tweet["text"].find(u"二郎") != -1: # 探せなかった場合は、-1が帰ってくる status_id = str(tweet["id"]) # まだリプしていないツイートがあったらリプする if status_id not in status_id_list: twitter.statuses.update(status="だったら、二郎行こうぜ", in_reply_to_status_id=status_id) status_id_list.append(status_id) if len(status_id_list) >= 20: # 20以上保持する必要はないので、必要に応じて減らす status_id_list = status_id_list[1:] time.sleep(60)
プログラムを動かしっぱなしにすることを想定しているため、time
で制御している
cron
などで定期的にプログラムを実行させる方法もある
(こちらの場合は、IDリストを外部ファイルに書き出す必要がある)