LoginSignup
5
2

More than 3 years have passed since last update.

今年1年を美味しそうなビールの写真とともに振り返る

Last updated at Posted at 2019-12-22

まえがき

今年は後半(転職後)が忙しく、コミュニティー活動も滞りがちになってしまって、関係各所に大変ご迷惑をおかけしました。
来年はもうちょっと調整して、いろいろできるようにしたいと思います(願望)

今年のアウトプット

昨年から参加している@tacckさん主催の、「ゆるWeb勉強会@札幌」で、「ある方」のTwitterのタイムラインに投稿されたビール画像を収集して表示するという、謎アプリを作って発表しました。

作成当時は、フレームワークも使用せず、コマンドラインから実行すると、ローカルのフォルダに取得した画像を格納するといいうものでしたが、その後、Flaskフレームワークを使用して、Web表示を行うように修正しています。

実際のソースコード

# Flask などの必要なライブラリをインポートする
import os
import json
import time
import lxml.html
import cssselect
import itertools
import re
from datetime import datetime, timedelta
from flask import Flask, render_template, request, redirect, url_for
from dotenv import load_dotenv
from TwitterAPI import TwitterAPI

app = Flask(__name__)

load_dotenv()
CK = os.environ.get('CONSUMER_KEY')
CS = os.environ.get('CONSUMER_SECRET')
AT = os.environ.get('ACCESS_TOKEN')
ATS = os.environ.get('ACCESS_TOKEN_SECRET')

SEARCH_TERM = os.environ.get('TARGET_ACCOUNT')
api = TwitterAPI(CK, CS, AT, ATS)
mkdir_name = "bier_illustration"
reg_url = r"https?://[\w/:%#\$&\?\(\)~\.=\+\-]+"

data_next = '0'

# Tweetを取得
def get_target_word(keyword):
    global data_next
    # fullarchive start
    from_date_string = '200603210000'
    if (data_next == '***'):
        return []
    elif (data_next == '0'):
        print('first fetch')
        req = api.request('tweets/search/fullarchive/:bier', {'query': SEARCH_TERM + keyword, 'fromDate': from_date_string})
    else:
        print('next fetch:' + data_next)
        req = api.request('tweets/search/fullarchive/:bier', {'query': SEARCH_TERM + keyword, 'fromDate': from_date_string, 'next': data_next})
    # fullarchive end
    # 30days start
    '''
    from_date = datetime.now()
    from_date -= timedelta(days=30)
    from_date_string = from_date.strftime('%Y%m%d0000')
    req = api.request('tweets/search/30day/:bier', {'query': SEARCH_TERM + keyword, 'fromDate': from_date_string})
    if (data_next == '***'):
        return []
    elif (data_next == '0'):
        print('first fetch')
        req = api.request('tweets/search/30day/:bier', {'query': SEARCH_TERM + keyword, 'fromDate': from_date_string})
    else:
        print('next fetch:' + data_next)
        req = api.request('tweets/search/30day/:bier', {'query': SEARCH_TERM + keyword, 'fromDate': from_date_string, 'next': data_next})
    '''
    # 30days end
    timeline = json.loads(req.text)
    try:
        data_next = timeline['next']
    except KeyError:
        data_next = '***'
    finally:
        return timeline

# 取得したツイートに画像があれば、その画像を取得する
def get_illustration(timeline):
    biers = []
    try:
        for tweet in timeline['results']:
            bier_dic = {}
            time_stirng = time.strftime('%Y-%m-%d', time.strptime(tweet['created_at'],'%a %b %d %H:%M:%S +0000 %Y'))
            # tweetから直接画像を取得
            extended_entities = tweet.get('extended_entities')
            if extended_entities == None:
                pass
            else:
                media_list = tweet['extended_entities']['media']
                for media in media_list:
                    print('get twitter embedded picture')
                    bier_dic['url'] = media['media_url']
                    bier_dic['file_name'] = time_stirng + "_" + os.path.basename(media['media_url'])
            biers.append(bier_dic)
        return biers
    except KeyError:
        print('KeyError')
        return []
    except:
        import traceback
        traceback.print_exc()
        return []

# ここからウェブアプリケーション用のルーティングを記述
# index にアクセスしたときの処理
@app.route('/')
def index():
    all_biers = []
    # 検索対象の単語を設定
    while True:
        keyword = os.environ.get('TARGET_KEYWORD')
        timeline = get_target_word(keyword)
        ret_bier = get_illustration(timeline)
        if ret_bier == []:
            print('no data')
            break
        else:
            all_biers.append(ret_bier)
    # index.html をレンダリングする
    return render_template('index.html', biers=list(itertools.chain.from_iterable(all_biers)), title=os.environ.get('TITLE'))

if __name__ == '__main__':
    app.debug = True # デバッグモード有効化
    app.run(host='127.0.0.1') # どこからでもアクセス可能に

ソースコードについて

本エントリーのタイトルにもある通り、完全にネタなのですが、ソースコード自体は普通のTwitterAPIを利用した、画像収集プログラムです。内容的には難しいところはありませんが、TwitterのAPIの仕様が完全に把握できておらず、現在のところまだバグがあります。(100件を超える分のTweetが取得されない)
これ以外にテンプレート等もありますが、大した内容ではないので省略します。

実行結果

スクリーンショット 2019-12-22 11.31.53.png

終わりに

来年の勉強会に向けて、このプログラムを発展させて、機械学習などもやってみたいと思っています。
来年もどうぞよろしくお願いいたします。>関係者各位

5
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2