Twitterは単なるニュースの拡張ソースではなく、世界中の人々の考えを示す群を抜いて優れたサンプルの1つです。3億3,000万人以上の月間アクティブユーザーを抱えるTwitterは、人々が自分の考えを共有することを好むトッププラットフォームの1つです。Twitterのデータは、以下のようなさまざまな目的に使用できます。研究, 消費者インサイト, デモグラフィックインサイト、その他多数。
したがって、このチュートリアルの主な目的は、プロジェクトやビジネスに関連するTwitterデータのサンプルを取得する方法を説明することです。
進める前に、以下の変数がすべて手元にあることを確認してください。
- Consumer Key
- Consumer Secret
- Access Token
- Access Token Secret
上記の詳細情報を取得する方法を知りたい場合は、以下をお読みください。同僚のDattatray Upaseが執筆したブログ記事.
それでは、コーディングを始めましょう!
入力変数の定義
まず、プログラムに必要なグローバル変数をいくつか定義する必要があります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import sys start_date = sys.argv[1] #"2018-01-09" end_date = sys.argv[2] #"2018-01-10" consumerKey="ここに_Consumer_Key_を入力" consumerSecret="ここに_Consumer_Secret_を入力" accessToken="ここに_Access_Token_を入力" accessTokenSecret="ここに_Access_Token_Secret_を入力" keyword= sys.argv[3] #"tcs" lang="en" #Twitterが提供している言語フィルタリングを確認してください data={} |
コマンドライン引数を取得するために、「sys」をインポートしています。キーワード、開始日、終了日を変更したい場合があるためです。言語には英語を選択しましたが、他にどのような言語がサポートされているか確認することをお勧めします。結果は最終的に「data」に保存されます。
その結果、スクリプトの一般的な使用方法は次のようになります。
python script.py start_date end_date keyword
Twitter APIへのアクセス
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import oauth2 req_count = 0 def oauth_req(url, http_method="GET", post_body=b"", http_headers=None): global req_count,consumerKey,consumerSecret,accessToken,accessTokenSecret req_count += 1 consumer = oauth2.Consumer(key=consumerKey, secret=consumerSecret) token = oauth2.Token(key=accessToken, secret=accessTokenSecret) client = oauth2.Client(consumer, token) resp, content = client.request( url, method=http_method, body=post_body , headers=http_headers ) return content |
変数 req_count は、プログラムの実行中にAPIを使用した回数です。提供されたコードで次のエラーが発生しています。
TypeError: Unicode-objects must be encoded before hashing
これを回避するために、post_body=”” を post_body=b”” に変更しており、 これにより問題が解決します。
Twitter APIの使用方法とリファレンス
Twitterデータを取得するためのAPI URLを設定しましょう。ここでは、パラメータmin_favesを使用しています。以下に、URLの説明といくつかの最適化のコツを紹介します。
「min_faves」 は、データ内でツイートが持つべき最小のお気に入り数を設定するために使用されます。非常に便利な機能ですが、Twitter APIのドキュメントには記載されていません。
‘q’ は、入力したいクエリまたはキーワードを表します。ここで重要なのは、指定するキーワードをできるだけ少なくすることです。例えば、FacebookとGoogleに関するツイートを取得したいとします。両方をキーワードとして(例えば「FACEBOOK」と「GOOGLE」)指定すると、制限があるため最大100件のツイートしか返されません。しかし、クエリを2回実行し、1回目はFacebook、2回目はGoogleで実行すれば、合計200件のツイートを取得できます。要するに、1回のクエリにつき1つのキーワードを使用するのが最善です。
‘lang’ は、フィルタリングされたツイートの言語を表します。英語のツイートを取得したいため、‘en’に設定しています。
‘since’ は、ツイートを検索したい期間の開始日です。この開始日は過去7日以内である必要があります。これもTwitter APIドキュメントに記載されていない機能です。
‘until’ は、希望する期間の終了日を表します。論理的には、これも過去7日以内である必要があります。これもTwitter APIドキュメントには記載されていません。
‘result_type’ は、取得したいツイートの種類を表します。これには3つの値があります:
‘recent’ は、最新のツイート、つまり選択した期間の終わりのツイートを返します。
‘popular’ は、最も人気のあるツイートを返すため、多くのツイートを見落とすことになります。常にお気に入り数やリツイート数が多い上位のツイートが取得されます。 min_faves 機能はここでは役に立ちません。
‘mixed’ は、最新のツイートと人気のツイートを混ぜて返します。
‘count’ は、結果に含まれるツイートの最大数を表します。デフォルトは15に設定されており、最大値は100です。
混合の result_type と min_faves の使用により、クエリを複数回実行して最大のツイート数を取得できます。
|
1 2 3 |
def get_tweets(min_faves): global keyword, start_date, end_date, lang return oauth_req( 'https://api.twitter.com/1.1/search/tweets.json?' + '&q=' + keyword + '&lang=' + lang + '%20since%3A' + start_date + '%20until%3A' + end_date + '%20min_faves%3A' + str(min_faves) +'&result_type=mixed&count=100') |
さらに多くのドキュメント化された機能については、以下も確認してください: TwitterのAPIドキュメント.
取得したツイートデータの保存/自動保存
次のステップとして、パラメータ「saveOverride」を持つ自動保存/保存メソッドを定義する必要があります。このステップは、単に自動保存の時間制限を解除してファイルを保存するために必要です。これを行うために、私は t_last を作成してプログラムの開始時間を保存します。次に、プログラム内でこれにアクセスし、t_last(最後の保存時間)から5分が経過したかどうかを確認します。5分以上経過している場合は、「saveStatus」をTrueに設定します。
次に、「saveOverride」を確認します。これは単に、何があっても今すぐファイルを保存するようにプログラムに指示を出す必要があることを意味します。このため、saveStatusをTrueに設定します。
そして、「saveStatus」がTrueの場合、スクリプトは t_last を現在の時間に変更します。その後、コードは辞書オブジェクトを作成し、“[time]に自動保存” と出力し、データが自動保存されていることがわかるようにします。
次に、出力ファイルがすでに存在するかどうかを確認します。存在する場合は、データとすでに保存されているファイルのデータを結合します。結合後、同じファイルに書き込みます。存在しない場合は、新しいファイルを作成し、そのファイルにデータを書き込みます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import os import json import time import datetime t_last = time.time() def autosave(saveOverride = False): global t_last saveStatus = (time.time() > t_last + 300) if(saveOverride == True):en" saveStatus = True if(saveStatus): t_last=time.time() tmp = {} print("Autosave at " + str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))) fnamea = keyword + "-st-" + start_date + "-ed-"+ end_date + '.json' if os.path.exists(fnamea) == True: with open(fnamea,'r+') as f: tmp = json.load(f) for i in data.keys(): tmp[i] = data[i] with open(fnamea,'w+') as f: json.dump(tmp,f) |
その結果、私が望んでいた機能のほぼすべてをコーディングすることができました。
さらなる最適化
最後に、これらの関数を使用する時が来ました。私はwhile(1)ループ、つまりwhile(True)を記述しています。これにより、基本的に何らかの‘break’ステートメントが呼び出されるか、例外が発生するまで、命令が永続的に実行されます。
まず、json.loadsを使用して辞書「d」にツイートデータを収集します。これはデータを辞書形式に変換します。次に、try-catch/exceptを、データからステータスを抽出するコードブロックに対して実行します。Twitter APIがデータを返さず、エラーを記載したJSONを返すことがあるため、try-catchを使用します。そのような場合にプログラムを停止させたくありません。また、それが何回目のリクエストで発生しているかを取得し、自動保存コマンドを使用してTwitterデータを保存したいと考えています。Twitterでは15分間に180回のリクエストを送信できます。これは1分間に約12回、または5秒に1回のリクエストに相当します。念のため、1回のイテレーションを実行した後にプログラムを5秒間スリープさせるsleepコマンドを追加します。
その後、コードはスクリプトがこれまでに収集したツイート数を表示します。
最後に、主要な最適化のトリックの出番です。私はこのスクリプトをほぼ1週間テストし、各min_favesの値に対して以下のツイート数を取得しました。1回のリクエストで最大100件のツイートを取得できるため、できるだけ多く取得したいと考えています。現在、min_favesの値が高いツイートは多くありませんが、企業やキーワードがトレンドになっている場合を考慮したいと考えています。最大値はmin_favesで、999999にすることができます。
| min_favesの値 | ツイート数 |
| 100,000 | 1 |
| 90,000 | 1 |
| 80,000 | 1 |
| 70,000 | 2 |
| 60,000 | 3 |
| 50,000 | 6 |
| 40,000 | 6 |
| 30,000 | 12 |
| 25,000 | 12 |
したがって、私はmin_favesの値が60000からツイートを取得し、10000に達するまで毎回10000ずつ減らしていくロジックを使用しています。しかし、たとえばキーワードがトレンドになっており、min_favesの値を30000にして作業しているときに100件のツイートを取得した場合、min_favesを増やすことになります。 35000にして、再度結果を取得します。そのため、新しいロジックは10000ではなく5000になります。ただし、変化量が1000未満に減少した場合は、それを無視して1000を引く処理を進めるように指示します。
固定の間隔1000を指定しており、これによってmin_favesは、もしmin_favesが10000以下の場合に減少します。
プログラムの最後には、‘End’と表示されることで、処理が完了したことをプログラムが知らせてくれます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
min_faves=60000 change=10000 #データを抽出するためのmin_favesの大幅な削減 interval = 500 #データを抽出するためのmin_favesの通常の削減 while(1): d = json.loads(get_tweets(min_faves)) try: for i in d['statuses']: data[i['id']] = i c = len(d['statuses']) except Exception as e: print("Error at request : " + str(req_count)) autosave(True) print("At request: " + str(req_count) + " Total Tweets Collected: " + str(len(data)) + " with Min Faves: " + str(min_faves) ) if c==100 and min_faves>10000: if (change>1000): change /= 2 min_faves += change else: min_faves -= change elif min_faves>10000: min_faves -= change else: min_faves -= interval if(min_faves < 0): fnamea = keyword + '.json' autosave(True) break autosave() time.sleep(5) print("End") |
コード全体は、以下で確認できます:GitHub.
以上です。次回のTwitterデータチュートリアルでは、ビッグデータツール‘Flume’を使ってリアルタイムのツイートを取得する方法を解説します。お楽しみに!
コメント
コメントはまだありません。最初のコメントを投稿しましょう。