見出し画像

twitter API

DataCampIntermediate Importing Data in Pythonコースを学習しています。

ようやく最後のチャプター、③Diving deep into the Twitter APIです。Twitter APIからデータをストリーミングします。ストリーミングとはファイルをダウンロードしながら再生をすることのようです。

・Twitter APIからデータをストリーミングする方法

・入ってくるツイートをキーワードでフィルタリングする方法

・API認証とOAuthの原則

・Tweepyの使い方


Twitter APIにアクセスするには、まずはTwitter アカウントが必要。英語の質問が多くて初見だとめげます…。


DataCampの言う通りのコードを実行してみます。tweepyはインストールする必要がありました。


import tweepy, json
access_token="**********************************************"
access_token_secret="**********************************************"
consumer_key="**********************************************"
consumer_secret="**********************************************"
auth=tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

APIキーとシークレットをハンドラーに渡す。次に、set_access_tokenを使用して、アクセス資格情報に渡す。

class MyStreamListener(tweepy.StreamListener):
   def __init__(self, api=None):
       super(MyStreamListener, self).__init__()
       self.num_tweets=0
       self.file=open("tweets.txt", "w")
   def on_status(self, status):
       tweet=status._json
       self.file.write(json.dumps(tweet)+'\\n')
       tweet_list.append(status)
       self.num_tweets+=1
       if self.num_tweets<100:
           return True
       else:
           return False
       self.file.close()

Twitterストリームリスナークラスを定義する。tweets.txtというファイルを作成し、ストリーミングツイートを収集して書き込む。100のツイートがストリーミングされるとファイルを閉じてリスニングを停止する。

json.dump(変数)はPythonのデータ構造をJSONに変換して出力する。

l=MyStreamListener()
stream=tweepy.Stream(auth, l)
stream.filter(track=['apples', 'oranges'])

インスタンスを作成し、それを認証する。

次に、フィルターメソッドをオブジェクトストリームに適用することで、選択したキーワードを含むツイートをストリーミングできる。

実行してみると…

NameError: name 'tweet_list' is not defined

エラー。確かに、tweet_listは定義されていませんね…。

DataCampを彷徨うと、その後のExerciseでYou can find the code for the tweet stream listener class here.のリンクをクリックすると

class MyStreamListener(tweepy.StreamListener):
   def __init__(self, api=None):
       super(MyStreamListener, self).__init__()
       self.num_tweets = 0
       self.file = open("tweets.txt", "w")
   def on_status(self, status):
       tweet = status._json
       self.file.write( json.dumps(tweet) + '\n' )
       self.num_tweets += 1
       if self.num_tweets < 100:
           return True
       else:
           return False
       self.file.close()
   def on_error(self, status):
       print(status)

修正されたwitterストリームリスナークラスがありました!!

これで動いた!でもめちゃくちゃ時間かかります。

止まったと思ったらエラーが表示されました。

ProtocolError: ('Connection broken: IncompleteRead(2 bytes read)', IncompleteRead(2 bytes read))

でもtweets.txtは作成されているのでOKとしましょう。


次はexerciseと少し変えて、python, JavaScript, Ruby, Swiftの単語でフィルターをかけてみます。C++入れたかったけど、エラーになったので除外しました…。

stream.filter(track=['python', 'JavaScript', 'Ruby','Swift'])


次にローカルに保存したtweets.txtをロードして、探検します。

import json
tweets_data_path='tweets.txt'
tweets_data=[]
tweets_file = open(tweets_data_path, "r")
for line in tweets_file:
   tweet=json.loads(line)
   tweets_data.append(tweet)
tweets_file.close()
print(tweets_data[0].keys())

<出力>
dict_keys(['created_at', 'id', 'id_str', 'text', 'source', 'truncated', 'in_reply_to_status_id', 'in_reply_to_status_id_str', 'in_reply_to_user_id', 'in_reply_to_user_id_str', 'in_reply_to_screen_name', 'user', 'geo', 'coordinates', 'place', 'contributors', 'quoted_status_id', 'quoted_status_id_str', 'quoted_status', 'quoted_status_permalink', 'is_quote_status', 'quote_count', 'reply_count', 'retweet_count', 'favorite_count', 'entities', 'favorited', 'retweeted', 'filter_level', 'lang', 'timestamp_ms'])

tweets.txtは1行が{"created_at" : "…" , "id": …, …}といった一つのツイートのデータ。これはJSONの形式なので、json.loads()

tweets_dataという空のリストを作成し、JSON形式のツイートを入れていきます。tweets_data[0]の型はdictです。


# Import package
import json
# String of path to file: tweets_data_path
tweets_data_path='tweets2.txt'
# Initialize empty list to store tweets: tweets_data
tweets_data=[]
with open(tweets_data_path, "r") as file:
   text=file.read()

for line in text:
   tweets_data.append(line)
print(tweets_data)

少し自分でも変えてみようと思い、JSONじゃなくてもいいのかな、とコードを試したら

画像3

あれ~?


twitter dataをDataFrameへ

tweets_dataをDataFrameにして、上位5つがどんなツイートか、どの言語かを出力します。

import pandas as pd
df = pd.DataFrame(tweets_data, columns=['text','lang'])
print(df.head())

画像2

ptはポルトガル語かな?undはundefinedみたいです。絵文字だけだから?


テキストを解析する

python, JavaScript, Ruby, Swiftを含むツイートがいくつあるか数えてみましょう。

まずはword_in_text()関数を定義します。第一引数(単語)が、第二引数(ツイート)内に存在するかどうかを教えてくれる。

import re
def word_in_text(word, text):
   word = word.lower()
   text = text.lower()
   match = re.search(word, text)
   if match:
       return True
   return False

正規表現モジュール re、先頭に限らずマッチするかチェック

画像3


python, javascript, ruby, swift = 0, 0, 0, 0
for index, row in df.iterrows():
   python += word_in_text('python', row['text'])
   javascript += word_in_text('JavaScript', row['text'])
   ruby += word_in_text('Ruby', row['text'])
   swift += word_in_text('Swift', row['text'])

df.iterrows()メソッドは、1行ずつそのインデックス名(行名)とそのデータのタプルを取得します。つまり、1ツイートずつ取得します。


グラフにしてみましょう。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
cd = ['python', 'JavaScript', 'Ruby','Swift']
ax = sns.barplot(cd,[python, javascript,ruby, swift])
ax.set(ylabel="count")
plt.show()

画像4

他の言語に比べて、Swiftが圧倒的に多いですね。これはテイラースウィフトなども含んでいるからでは??

この記事が気に入ったらサポートをしてみませんか?