TomoProgの技術書

底辺プログラマーが達人プログラマーになるまで

Pythonで百人一首ボットを作ってみる!! パート2

皆さん
こんにちは、こんばんは
TomoProgです。

前の投稿から少し期間が空いてしまいましたが気にせず、書いていこうと思います。
今回は百人一首ボット作りのパート2です!!

パート1を見ていない方はパート1からどうぞ!!
tomoprog.hatenablog.com

パート1では絵札をTwitterに投稿するところまで出来ました。
今回は絵札と一緒に歌も投稿してみたいと思います。

それでは頑張っていきましょう。

歌と歌人を集める

まずは歌の上の句、下の句を集めるところからスタートです。
今回は以下のサイトを利用し、集めてみます。
百人一首の一覧

集め方はこんな感じです。

  1. 上記のサイトを全コピーし、テキストエディタにペースト
  2. 空行などの不必要な行を全削除して保存
  3. 保存したテキストファイルを表計算ソフトで開く
  4. CSVファイルとして保存

プログラムは一行も書きません!!

実際にやってみると、こんな感じです。
f:id:TomoProg:20160224225421j:plain

次は歌人を集めます。
と言ってもさっきとサイトが違うだけで、やり方はほぼ一緒です。
利用したサイトは以下のサイトです。
小倉百人一首の歌人名前・読み方

これで歌と歌人は準備出来ました。

jsonフォーマットに整形してみる

先ほど作ったCSVファイルのまま使用してもいいのですが、今回は勉強も兼ねてjsonフォーマットに整形してみました。
Pythonにはjsonというjsonファイルを扱う標準モジュールがあります。
19.2. json — JSON エンコーダおよびデコーダ — Python 3.6.5 ドキュメント

jsonモジュールを使って以下のCSV形式のテキストファイルを読み込んで、jsonフォーマットに整形してみます。

CSVファイル:
天智天皇,てんじてんのう,秋の田のかりほの庵の苫をあらみ,わが衣手は露にぬれつつ
持統天皇,じとうてんのう,春過ぎて夏来にけらし白妙の,衣干すてふ天の香具山
柿本人麻呂,かきのもとのひとまろ,あしびきの山鳥の尾のしだり尾の,ながながし夜をひとりかも寝む
(以下省略・・・)
#-*- coding:utf-8 -*-

import json

json_info = []
cnt = 1

with open("karuta_info.csv") as f:
    f_str = []
    for line in f:
        f_str.append(line)

for line in f_str:
    d = {}
    line = line.rstrip("\n")
    info = line.split(",")
    info.append(str(cnt).zfill(3) + ".jpg")
    d["name"] = info[0]         # 歌人名
    d["hurigana"] = info[1]     # ふりがな
    d["first_part"] = info[2]   # 上の句
    d["last_part"] = info[3]    # 下の句
    d["img"] = info[4]          # 画像名
    json_info.append(d)
    cnt += 1

with open("karuta_info.json", "w") as f_json:
    for info in json_info:
        json.dump(info, f_json, sort_keys=True, indent=4, ensure_ascii=False)
        f_json.write("\n")
実行結果:
{
    "first_part": "秋の田のかりほの庵の苫をあらみ",
    "hurigana": "てんじてんのう",
    "img": "001.jpg",
    "last_part": "わが衣手は露にぬれつつ",
    "name": "天智天皇"
}
{
    "first_part": "春過ぎて夏来にけらし白妙の",
    "hurigana": "じとうてんのう",
    "img": "002.jpg",
    "last_part": "衣干すてふ天の香具山",
    "name": "持統天皇"
}
{
    "first_part": "あしびきの山鳥の尾のしだり尾の",
    "hurigana": "かきのもとのひとまろ",
    "img": "003.jpg",
    "last_part": "ながながし夜をひとりかも寝む",
    "name": "柿本人麻呂"
}
(以下省略・・・)

json.dumpを使えば辞書型から簡単にjsonフォーマットに変換できるので便利です!!

つぶやいてみる

百人一首の情報を一つのjsonファイルにまとめたので、あとは読み込んでTwitterに投稿するだけです!!
早速やってみましょう。

#-*- coding:utf-8 -*-

from twitter import *
import json
import datetime
import time
import random
import copy
import os

# global変数
app = None
app_up = None
app_auth = None
conf_file_name = "conf.json"
karuta_info_file_name = "karuta_info.json"

def main():
    """
        Content:
            エントリーポイント
    """

    global app
    global app_up
    global app_auth
    global conf_file_name
    global karuta_info_file_name

    # 設定ファイル読み込み
    with open(conf_file_name) as f:
        conf_data = json.loads(f.read())

    # Twitterアプリ認証
    app_auth = OAuth(conf_data["access_token"],
                conf_data["access_token_secret"],
                conf_data["consumer_key"],
                conf_data["consumer_secret"])
    app = Twitter(auth=app_auth)
    app_up = Twitter(domain="upload.twitter.com", auth=app_auth)

    # 百人一首ファイル読み込み
    karuta_info = []
    with open(karuta_info_file_name) as f:
        for line in f:
            karuta_info.append(json.loads(line))

    # 初回起動メッセージをつぶやく
    tweet_time = datetime.datetime.now()
    tweet_msg = """
                karuta_bot.pyが起動したよ!!
                これから5分毎に百人一首をつぶやくよ!!
                """
    app.statuses.update(status=tweet_msg)

    # 5分毎につぶやく
    tweet_karuta_list = copy.deepcopy(karuta_info)
    while True:
        now_time = datetime.datetime.now()
        if int((now_time - tweet_time).seconds / 300) >= 1:
            idx = random.randint(0, len(tweet_karuta_list) - 1)
            karuta_tweet(tweet_karuta_list.pop(idx))
            if not tweet_karuta_list:
                tweet_karuta_list = copy.deepcopy(karuta_info)
            tweet_time = now_time
        time.sleep(10)

def karuta_tweet(karuta_info):
    """
        Content:
            つぶやく
    """

    global app
    global app_up

    # 画像アップロード
    file_path = os.path.join("./karuta_img/", karuta_info["img"])
    with open(file_path, "rb") as image_f:
        image_data = image_f.read()
    id_img = app_up.media.upload(media=image_data)["media_id_string"]

    tweet_msg = (karuta_info["first_part"] + "\n" +
                karuta_info["last_part"] + "\n" +
                karuta_info["name"])

    # 画像とメッセージを投稿
    app.statuses.update(status=tweet_msg, media_ids=id_img)

if __name__ == "__main__":
    main()

jsonファイルから1首ランダムに選び出して、Twitterに投稿しています。

実際に起動してみた様子はこんな感じです。
毎日百人一首くん (@TomoProgBot) | Twitter
f:id:TomoProg:20160225002145j:plain

これでTwitterに自由に画像付きツイートを投稿出来そうです!!

今日の成果

  • 画像と同時に歌と歌人を投稿できた!!
  • jsonモジュールの使い方を勉強できた!!

あとは現代語訳を投稿するだけですね。
次で完成しそうです!!

それではまた。

TomoProg

GitHub
TomoProg (TomoProg) · GitHub

Twitter
TomoProg (@tomoprog_xxx) | Twitter