このページに書かれている内容はTwitter APIの有料化により無料では使用できなくなっています.
あるアカウントのツイートに関する情報を取得し,ツイートの傾向を調べます. 具体的には,フォローしているアカウントの直近1000件のツイート情報を取得し,ツイートの文字数 リプライの割合 RTの割合 平均いいね数 平均RT数 最近30日でのツイート数を調べます.
APIキー アクセストークンを使ってAPIオブジェクトを作成します. 以下のコードをコピペしてAPIキー アクセストークンの部分だけ書き換えてください. 今回はAPIオブジェクトの作成時にwait_on_rate_limitを設定してレート制限によるエラーを回避します. APIキー アクセストークンを忘れた方はアクセストークン・API Keyについてをご覧ください.
# tweepy.__version__ == '4.12.1'
import tweepy
# アクセストークンなどの識別コードを入力します
access_token= "Access Tokenを入力してください"
access_secret = "Access Token Secretを入力してください"
api_key = "API Keyを入力してください"
api_key_secret = "API Key Secretを入力してください"
bearer_token = "Bearer Tokenを入力してください"
# APIオブジェクトを作成します
auth = tweepy.OAuthHandler(api_key, api_key_secret)
auth.set_access_token(access_token, access_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
特定のユーザーのフォロー・フォロワーを確認するで紹介した方法でフォローリストを作成します. 自分のツイートの傾向も調べたい場合は,follow_sn_listに自分のscreen_nameも追加します.
import datetime
import pickle
import os
follow_id_list = []
cursor = -1 # 最初の位置は-1で指定します
# すべて読み込み終わったら cursor=0 になります
while cursor!=0:
id_cursor = api.get_friend_ids(cursor=cursor)
follow_id_list += id_cursor[0] # フォローしているアカウントのIDをfollow_id_listに追加します
cursor = id_cursor[1][1] # [previous_cursor, next_cursor]の順に格納されています
# @abc... に直す
follow_sn_list = []
for i in range(0, len(follow_id_list), 100):
# 15分で900件まで
for user in api.lookup_users(user_id=follow_id_list[i:i+100]):
follow_sn_list.append(user.screen_name)
# 自分のIDも追加したい場合
# my_screen_name= "ここに自分のscreen_nameを入力してください"
# follow_sn_list.append(my_screen_name)
特定のユーザーのツイートを取得するで紹介した方法でツイートを取得します. 取得した情報はpickleで保存します.
import math
import pickle
cnt = 0
tweet_info_dict = {}
for screen_name in follow_sn_list:
cnt += 1
print(f"{cnt} @{screen_name}")
# ツイートを取得したいユーザーのツイート数を調べる
user = api.lookup_users(screen_name=[screen_name])
loop_count = min(5,math.ceil(user[0].statuses_count/200)) # 200で割って切り上げ
tweet_list = []
max_id = None
while loop_count>0:
tweets = api.user_timeline(count=200,screen_name=screen_name,max_id=max_id)
# 1件もツイートが取得できなかったときにエラーになるのを防ぐ
if len(tweets) == 0:
print("ツイートを取得できませんでした",loop_count)
loop_count = 0
else:
max_id = tweets[-1].id - 1 # 取得したツイートの最後のIDから1引いたものをmax_idにすれば続きから取得できる
loop_count -= 1
tweet_list += tweets # 取得したツイートをリストに追加する
tweet_info_list = []
for tweet in tweet_list:
# リプライか否かの情報
if tweet.in_reply_to_user_id == None:
reply_flag = 0
else:
reply_flag = 1
# RTか否かの情報 RTでなければ "retweeted_status" は存在しない
if "retweeted_status" not in tweet._json.keys():
rt_flag = 0
else:
rt_flag = 1
tweet_info_list.append((tweet.created_at,len(tweet.text),tweet.retweet_count,tweet.favorite_count,reply_flag,rt_flag)) # 日時, ツイートの文字数, RT数, いいね数, リプライか否か, RTか否か
tweet_info_dict[screen_name] = tweet_info_list
# ツイートに関する情報を保存
with open("TweetInfoDict.pkl", "wb") as tf:
pickle.dump(tweet_info_dict,tf)
ツイートの情報を読み込んで傾向を調べます. 後でランキング形式で表示できるようにuser_info_dictを作ってそこに情報を記録していきます.
import pickle
with open("TweetInfoDict.pkl", "rb") as tf:
tweet_info_dict = pickle.load(tf)
# tweet_info_dict と同じkeyを持つ辞書の辞書を作る
user_info_dict = {screen_name:{} for screen_name in tweet_info_dict.keys()}
RT,リプライ以外のツイート(通常のツイート)の平均文字数かを調べて,user_info_dictに記録します.
# tweet_info_dict[screen_name] = [日時, ツイートの文字数, RT数, いいね数, リプライか否か, RTか否か]
for screen_name in tweet_info_dict.keys():
tweet_info_list = tweet_info_dict[screen_name]
text_length = 0
normal_tweet_num = 0
for tweet_info in tweet_info_list:
# RT でも リプライでもない場合のみ調べる
if tweet_info[4]==0 and tweet_info[5]==0:
text_length += tweet_info[1]
normal_tweet_num += 1
if normal_tweet_num==0:
print(f"@{screen_name} None")
user_info_dict[screen_name]["average_text_length"] = -1
else:
print(f"@{screen_name} {round(text_length/normal_tweet_num,1)}文字")
user_info_dict[screen_name]["average_text_length"] = round(text_length/normal_tweet_num,1)
print("======================")
通常のツイート,RT,リプライの割合をそれぞれ調べます.
# tweet_info_dict[screen_name] = [日時, ツイートの文字数, RT数, いいね数, リプライか否か, RTか否か]
import datetime
for screen_name in tweet_info_dict.keys():
tweet_info_list = tweet_info_dict[screen_name]
rt_num = 0
reply_num = 0
normal_tweet_num = 0
for tweet_info in tweet_info_list:
# RTかどうか判定
if tweet_info[5]==1:
rt_num += 1
# リプライかどうか判定
elif tweet_info[4]==1:
reply_num += 1
else:
normal_tweet_num += 1
print(f"@{screen_name}")
if len(tweet_info_list)!=0:
print(f"通常のツイート {normal_tweet_num}, {round(normal_tweet_num*100/len(tweet_info_list),1)}%")
print(f"リプライ {reply_num}, {round(reply_num*100/len(tweet_info_list),1)}%")
print(f"RT {rt_num}, {round(rt_num*100/len(tweet_info_list),1)}%")
else:
print("ツイートがありません")
user_info_dict[screen_name]["tweet_num"] = len(tweet_info_list)
user_info_dict[screen_name]["normal_tweet_num"] = normal_tweet_num
user_info_dict[screen_name]["reply_num"] = reply_num
user_info_dict[screen_name]["rt_num"] = rt_num
print("============================")
通常のツイートの平均RT,いいね数を調べます.
# tweet_info_dict[screen_name] = [日時, ツイートの文字数, RT数, いいね数, リプライか否か, RTか否か]
for screen_name in tweet_info_dict.keys():
tweet_info_list = tweet_info_dict[screen_name]
rt_num = 0
favorite_num = 0
normal_tweet_num = 0
for tweet_info in tweet_info_list:
# RT,リプライは除外
if tweet_info[4]==0 and tweet_info[5]==0:
rt_num += tweet_info[2]
favorite_num += tweet_info[3]
normal_tweet_num += 1
print(f"@{screen_name}")
if normal_tweet_num!=0:
print(f"RT {rt_num} 平均RT数 {round(rt_num/normal_tweet_num,1)}")
print(f"いいね {favorite_num} 平均いいね数 {round(favorite_num/normal_tweet_num,1)}")
user_info_dict[screen_name]["average_retweeted_num"] = round(rt_num/normal_tweet_num,1)
user_info_dict[screen_name]["average_favorite_num"] = round(favorite_num/normal_tweet_num,1)
else:
print("ツイートがありません")
user_info_dict[screen_name]["average_retweeted_num"] = -1
user_info_dict[screen_name]["average_favorite_num"] = -1
user_info_dict[screen_name]["retweeted_num"] = rt_num
user_info_dict[screen_name]["favorite_num"] = favorite_num
print("=========================")
最近30日のツイート数を通常のツイート,RT,リプライの種類別にカウントします. if time_delta.days <= 30: で時間に関する条件を付けた以外は上でやったものとほとんど同じです.
import datetime
# 日時, ツイートの文字数, RT数, いいね数, リプライか否か, RTか否か
for screen_name in tweet_info_dict.keys():
tweet_info_list = tweet_info_dict[screen_name]
cnt = 0
rt_num = 0
reply_num = 0
normal_tweet_num = 0
for tweet_info in tweet_info_list:
# tzinfoのない形に一度直す
year, month, day = tweet_info[0].year, tweet_info[0].month, tweet_info[0].day
time_delta = datetime.datetime.utcnow() - datetime.datetime(year,month,day)
if time_delta.days <= 30:
cnt += 1
if tweet_info[5]==1:
rt_num += 1
elif tweet_info[4]==1:
reply_num += 1
else:
normal_tweet_num += 1
print(f"@{screen_name}")
if cnt!=0:
print(f"通常のツイート {normal_tweet_num} {round(normal_tweet_num*100/cnt,1)}%")
print(f"リプライ {reply_num} {round(reply_num*100/cnt,1)}%")
print(f"RT {rt_num} {round(rt_num*100/cnt,1)}%")
else:
print("ツイートがありません")
user_info_dict[screen_name]["recent_tweet_num"] = cnt
user_info_dict[screen_name]["recent_normal_tweet_num"] = normal_tweet_num
user_info_dict[screen_name]["recent_reply_num"] = reply_num
user_info_dict[screen_name]["recent_rt_num"] = rt_num
print("======================")
辞書の並べ替えを使ってランキング形式で表示します. ['average_text_length', 'tweet_num', 'normal_tweet_num', 'reply_num', 'rt_num', 'favorite_num', 'retweeted_num', 'average_retweeted_num', 'average_favorite_num', 'recent_tweet_num', 'recent_normal_tweet_num', 'recent_reply_num', 'recent_rt_num'] の中から並び替えに使いたいkeyを指定することができます. ここでは平均文字数の多い順に並び替えています.
# 並び替えに使いたいkey
sort_key = "average_text_length"
# 並び替えたいデータの辞書を作る
ranking_data = {screen_name:user_info_dict[screen_name][sort_key] for screen_name in user_info_dict.keys()}
# 並び替え
ranking_data = sorted(ranking_data.items(), key = lambda x:x[1], reverse=True)
rank = 0
for data in ranking_data:
rank += 1
screen_name, num = data
print(f"{rank}位 @{screen_name} {num}")