【コード公開】Twitterのタイムラインをwordcloudにしてみた

【コード公開】Twitterのタイムラインをwordcloudにしてみた

皆さん、ワードクラウドって知ってますか?
ワードクラウドは文章内の言葉の頻出度を画像にしたものです。
多く含まれている言葉ほど、大きく画像に表示されます。

今回は、twitterのタイムラインをワードクラウドにするアプリをpythonで作成したので、紹介します。

準備

Twitter APIのアクセスキー取得

Mecab導入

wordcloudを使用するには、Mecabが必要になりますので、導入してください。

mecab-ipadic-neologd(Mecab) は、多数のWeb上の言語資源から得た新語を追加することでカスタマイズした MeCab 用のシステム辞書です。

下記サイトを参照し、Mecab導入する。

https://qiita.com/kenmatsu4/items/02034e5688cc186f224b#1-1mecab%E3%81%AE%E5%B0%8E%E5%85%A5

コード解説

メイン処理

inputでtwitterで検索するキーワードを入力し、for文で1週間分取得します。

##################################################################
## メイン処理

timelines = []
tweet_text = ''
# ツイートID
max_id = ''
# 検索ワード
keyword_filename = input('検索キーワードを入力してください')
keyword = keyword_filename + ' lang:ja -filter:retweets'
# ツイート取得対象日
dt_now = datetime.datetime.now()
start_dt = dt_now.strftime('%Y%m%d')

start_dt = datetime.datetime.strptime(start_dt, '%Y%m%d')
for i in range(7):
    dt = (start_dt - datetime.timedelta(days=i)).strftime('%Y-%m-%d')
    since = str(dt) + '_00:00:00_JST'
    until = str(dt) + '_23:59:59_JST'

    while True:
        check_api_remain_and_sleep()

        # ツイート検索
        max_id, texts = search_twitter_timeline(keyword, since, until, max_id)

        if texts == []:
            break

        for item in texts:
            tweet_text = tweet_text + item
        
        if len(texts) < SEARCH_LIMIT_COUNT:
            break

parse = mc.Tagger().parse(tweet_text)
lines = parse.split('\n')
items = (re.split('[\t,]', line) for line in lines)
output = []
for item in items:
    if item[0] == 'EOS':
        break

    if item[1] in ["名詞"]:
        output.append(item[0])

create_wordcloud(" ".join(output))

APIの利用回数制限チェック

TwitterのAPIには、利用制限があります。
15分ごとに利用回数が回復するため、利用回数が0回の場合は、待機する関数です。

# API利用回数に引っかかった場合に待機させる
def get_rate_limit_status():
    twitter = get_twitter_session()
    limit = 1
    remaining = 1
    reset_minute = 0

    req = twitter.get(RATE_LIMIT_STATUS_URL)
    if req.status_code == 200:
        limit_api = json.loads(req.text)

        limit = limit_api['resources']['search']['/search/tweets']['limit']
        remaining = limit_api['resources']['search']['/search/tweets']['remaining']
        reset = limit_api['resources']['search']['/search/tweets']['reset']
        reset_minute = math.ceil((reset - time.mktime(datetime.datetime.now().timetuple())) / 60)

    twitter.close()

    return limit, remaining, reset_minute

def check_api_remain_and_sleep():
    # APIの残り利用回数を取得
    limit, remaining, reset_minute = get_rate_limit_status()

    # APIの残り利用回数が0回の場合に回復するまで待機する
    if remaining == 0:
        time.sleep(60 * (int(reset_minute) + 1))

    return

twitterのタイムライン検索関数

基本的には、APIにパラメータを渡すことで、自動的にタイムラインを取得することができます。

TwitterのAPIでは、検索キーワードにオプションを使用することができます。
今回は、メイン関数にて下記のようなオプションを設定しています。

keyword = keyword_filename + ‘ lang:ja -filter:retweets’
 lang:ja = 日本語のみ検索
 -filter:retweets = リツイートを含めない

# キーワード検索で得られたツイートを取得する
# max_idを使用して次の100件を取得
def search_twitter_timeline(keyword, since='', until='', max_id=''):
    texts = []
    id = ''
    twitter = get_twitter_session()
    params = {'q': keyword, 'count': SEARCH_LIMIT_COUNT, 'result_type': 'mixed'}

    if max_id != '':
        params['max_id'] = max_id
    if since != '':
        params['since'] = since
    if until != '':
        params['until'] = until

    req = twitter.get(SEARCH_TWEETS_URL, params=params)

    if req.status_code == 200:
        search_timeline = json.loads(req.text)

        for tweet in search_timeline['statuses']:
            id = str(tweet['id'])
            # 次の100件を取得したときにmax_idとイコールのものはすでに取得済みなので捨てる
            if max_id == str(tweet['id']):
                continue
            texts.append(tweet['text'])
    else:
        print("ERROR: %d" % req.status_code)
    twitter.close()
    return id, texts

セッション確立関数

##################################################################
## トークン関連

CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET

##################################################################

# セッション確立
def get_twitter_session():
    return OAuth1Session(CK, CS, AT, ATS)

wordcloud作成関数

ストップワードに不要な文字列を設定することで、wordcloudに表示させなくさせることができます。

def create_wordcloud(text):
    # 環境に合わせてフォントのパスを指定する。
    fpath = "C:\\Windows\\fonts\\YuGothM.ttc"

    # ストップワードの設定
    stop_words = [u'てる', u'いる', u'なる', u'れる', u'する', u'ある', u'こと', u'これ', u'さん', u'して', \
                  u'くれる', u'やる', u'くださる', u'そう', u'せる', u'した', u'思う', \
                  u'それ', u'ここ', u'ちゃん', u'くん', u'', u'て', u'に', u'を', u'は', u'の', u'が', u'と', u'た', u'し', u'で', \
                  u'ない', u'も', u'な', u'い', u'か', u'ので', u'よう', u'', u'http', u'https', u'www', u'co', u'nhttp', u'nhttps']

    wordcloud = WordCloud(background_color="white", font_path=fpath, width=900, height=500, max_words=500, \
                          stopwords=set(stop_words)).generate(text)

    plt.figure(figsize=(15, 12))
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.show()

実行結果

キーワードをスターバックスとして実行した場合の結果