Twitter bot 分析機能[拡張編]
こんにちはkazutoです。今回は、分析機能を実装していきます。
事前準備
まずは事前準備を行っていきましょう。
下記のソースコードをコピペしてください。
require "./config.rb"
require "json"
require "open-uri"
require "csv"
require "./weather_class.rb"
require "./tweet.rb"
require "./search.rb"
require "./analysis.rb"
def execution
puts "メニューを選択してください"
puts "[1]天気予報を取得してツイートする"
puts "[2]5日間の天気情報を表示"
puts "[3]プロフィール編集"
puts "[4]ユーザ検索"
puts "[5]自己分析"
num = gets.to_i
case num
when 1
current_time_weather = wetaher(num)
tweet(current_time_weather,num)
when 2
current_time_weather = wetaher(num)
when 3
tweet(current_time_weather,num)
when 4
search()
when 5
analysis()
else
puts "無効な値です"
end
end
execution()
新たにAnalysisクラス(検索機能)を作成したいので、analysis.rbファイルを作成しましょう。
touch analysis.rb
ls analysis.rb
ファイルが作成できたら、クラスを定義をし、分析機能の雛形を整えましょう。事前準備ですが、少しメソッドの解説をしておきます。
class Analysis<Tweet
def initialize()
super(client)
end
def analysis_menu
puts "[1]タイムライン"
puts "[2]フォロー数"
puts "[3]フォロワー数"
puts "[4]タイムライン全件取得"
puts "[5]比較する"
num = gets.to_i
case num
when 1
timeline_style(@client.user.screen_name)
when 2
puts @client.user.friends_count
when 3
puts @client.user.followers_count
when 4
pages=number_of_pages_judgment(@client.user.screen_name)
get_all_tweets(nil,pages,{mode: "WRITE"} )
when 5
comparison_user_decision()
else
puts "無効の値です"
end
end
def comparison_user_decision()
puts "比較したいユーザのidを入力してください。"
user_name = gets.chomp
search_account_information(user_name,true)
comparison_user_menu(user_name)
end
def comparison_user_menu(user_name,search=false,search_target=nil)
puts "#{@client.user(user_name).name}さん"
puts "どの項目を比較しますか"
puts "[1]フォロー数"
puts "[2]フォロワー数"
puts "[3]ツイート数"
puts "[4]いいね数"
puts "[5]リツイート数"
num = gets.to_i
if search
# 検索したいユーザ + 比較したいユーザ
case num
when 1
#フォロー数を比較
when 2
#フォロワー数を比較
when 3
#ツイート数を比較
when 4
#いいね数を比較
when 5
#リツイート数を比較
else
puts "無効の値です"
end
else
# マイアカウント + 比較したいユーザ
case num
when 1
#フォロー数を比較
when 2
#フォロワー数を比較
when 3
#ツイート数を比較
when 4
#いいね数を比較
when 5
#リツイート数を比較
else
puts "無効の値です"
end
end
end
end
class Analysis<Tweet
今回もSearchクラスと同様、Tweetクラスの
- メソッド
- 属性(@clinet)
を使っていきたいので、Tweetクラスを継承します。クラスを継承する事で、親クラスのメソッドや属性を引き継ぐ事ができます
。
def initialize()
super(client)
end
Analysisクラスでは、特別に属性を持つ必要がないですが、アカウントの認証情報が格納されている、Tweetクラスの@clientは、いいね数などを取得するのに必要なので、Analysisクラスでも扱える様にsuperメソッドを用いています。
superメソッドとは親クラスにある同名のメソッドを呼び出すメソッドです
。
class Tweet
attr_accessor :client
end
今回の場合、スーパークラス(親クラス)でattr_accessorを用いてゲッターとセッターを定義しています。したがって、Analysisクラスでも同様に@cilentを使って値を参照する事が可能になります。
def analysis_menu
puts "[1]タイムライン"
puts "[2]フォロー数"
puts "[3]フォロワー数"
puts "[4]タイムライン全件取得"
puts "[5]比較する"
num = gets.to_i
case num
when 1
timeline_style(@client.user.screen_name)
when 2
puts @client.user.friends_count
when 3
puts @client.user.followers_count
when 4
pages=number_of_pages_judgment(@client.user.screen_name)
get_all_tweets(nil,pages,{mode: "WRITE"} )
when 5
comparison_user_decision()
else
puts "無効の値です"
end
end
まず初めにanalysis_menuメソッドを用いて、マイアカウントのメニュー欄を表示します。1~4までの項目は、「Twitter bot 検索機能[拡張編]」で同じ様な内容を実装したので、解説は省略させていただきます。分析機能のメインは「比較する」
という項目です。なので今回は、比較する項目に関わる内容を重点的に解説していきます。
when 5
comparison_user_decision()
比較するという項目を選択した場合は、comparison_user_decisionメソッドを呼び出します。
def comparison_user_decision()
puts "比較したいユーザのidを入力してください。"
user_name = gets.chomp
search_account_information(user_name,true)
comparison_user_menu(user_name)
end
comparison_user_decisionメソッドでは、比較したいユーザのidを入力し、比較する対象を決定します。
user_name = gets.chomp
search_account_information(user_name,true)
comparison_user_menu(user_name)
具体的な処理内容は、変数user_nameにユーザidを格納します。
search_account_informationメソッドを用いて、比較したいユーザを決定します。その後、comparison_user_menuメソッドを呼び出して、メニューを表示します。
def comparison_user_menu(user_name,search=false,search_target=nil)
puts "#{@client.user(user_name).name}さん"
puts "どの項目を比較しますか"
puts "[1]フォロー数"
puts "[2]フォロワー数"
puts "[3]ツイート数"
puts "[4]いいね数"
puts "[5]リツイート数"
num = gets.to_i
if search
# 検索したいユーザ + 比較したいユーザ
case num
when 1
#フォロー数を比較
when 2
#フォロワー数を比較
when 3
#ツイート数を比較
when 4
#いいね数を比較
when 5
#リツイート数を比較
else
puts "無効の値です"
end
else
# マイアカウント + 比較したいユーザ
case num
when 1
#フォロー数を比較
when 2
#フォロワー数を比較
when 3
#ツイート数を比較
when 4
#いいね数を比較
when 5
#リツイート数を比較
else
puts "無効の値です"
end
end
end
end
comparison_user_menuメソッドでは2つのパターンで比較する事が可能です。
- 検索したユーザ&比較するユーザ
- マイアカウント&比較するユーザ
if search
# 検索したユーザー + 比較したいユーザー
case num
end
else
# マイアカウント + 比較したいユーザー
case num
end
end
2つのパターンを再現をするために、上記の様に条件分岐をしています。
要するにユーザーが
- 検索したユーザと比較したいのか?
- マイアカウントと比較したいのか?
を選択できる様にプログラムを組みました。
以上で事前準備は、終了になります。次のトピックから本格的な実装になります
Twitter bot 分析機能[実装編]
- 比較に必要なメソッドを作成しよう
- フォロー&フォロワー&ツイート
- いいね&リツイート
- 検索機能と分析機能を連結させよう
比較に必要なメソッドを作成しよう
こちらのトピックでは、比較するという動作を再現するために必要なメソッドを作成していきます。分析機能の根幹部分
なので、ポイントを抑えておきましょう。
- make_users_informationメソッド
→比較するデータをハッシュ形式にまとめるメソッド - display_resultメソッド
→結果を表示するメソッド - result_of_comparisonメソッド
→データを比較するメソッド
上記の3つのメソッドを用いて、分析機能の根幹部分を実装していきましょう。
def make_users_information(user_name,type,items,search_target=nil)
case type
when "analysis"
myself=
{
name:@client.user.name,
result:items[:myself]
}
comparison_user=
{
name:@client.user(user_name).name,
result:items[:comparison_user]
}
return myself , comparison_user
when "search"
searchtarget=
{
name:@client.user(search_target).name,
result:items[:search_target_user]
}
comparison_user=
{
name:@client.user(user_name).name,
result: items[:comparison_user]
}
return searchtarget,comparison_user
else
puts "無効の値です"
end
end
def display_result(user,comparison_user,item_name)
puts "-------------------------------"
puts "#{item_name}"
puts "#{user[:name]}:#{ user[:result]}"
puts "#{comparison_user[:name]}:#{ comparison_user[:result]}"
puts "-------------------------------"
result_of_comparison(user,comparison_user)
end
def result_of_comparison(user,comparison_user)
puts user[:result] > comparison_user[:result] ? "#{ user[:name]}の方が#{user[:result]-comparison_user[:result]}多いです" : "#{ comparison_user[:name]}の方が#{comparison_user[:result]-user[:result]}多いです"
end
では、各メソッドごとに解説していきます。
def make_users_information(user_name,type,items,search_target=nil)
case type
when "analysis"
myself=
{
name:@client.user.name,
result:items[:myself]
}
comparison_user=
{
name:@client.user(user_name).name,
result:items[:comparison_user]
}
return myself , comparison_user
when "search"
searchtarget=
{
name:@client.user(search_target).name,
result:items[:search_target_user]
}
comparison_user=
{
name:@client.user(user_name).name,
result: items[:comparison_user]
}
return searchtarget,comparison_user
else
puts "無効の値です"
end
end
make_users_informationメソッドは、比較するデータをハッシュ形式にまとめるメソッド
です。
case type
when "analysis"
when "search"
else
puts "無効の値です"
end
case文を用いて、引数typeの値によって条件分岐を行っています。
- typeの値がanalysisだった場合
→マイアカウント&比較したいユーザの情報をハッシュ形式で返す - typeの値がsearchだった場合
→検索したユーザ&比較したいユーザの情報をハッシュ形式で返す
となります。
処理自体は同じなのですが一部、記述を変える必要があったので、上記の様に条件分岐を行いました。
#マイカウント
{
name:@client.user.name,
result:items[:myself]
}
#検索したユーザ
{
name:@client.user(search_target).name,
result:items[:search_target_user]
}
#比較したいユーザ
{
name:@client.user(user_name).name,
result: items[:comparison_user]
}
データ構造は、
- name
→そのアカウントの名前 - result
→選択した項目の数
となります。
return myself,comparison_user
return searchtarget,comparison_user
a,b = make_users_information(#引数)
make_users_informationメソッドで重要な部分は、返り値が2つあるという事
です。したがって返り値を受け取る際は、分割代入を用います。
以上で、make_users_informationメソッドの解説は終了です。続いて、結果を表示するメソッド
display_resultメソッドの解説をします。
def display_result(user,comparison_user,item_name)
puts "-------------------------------"
puts "#{item_name}"
puts "#{user[:name]}:#{ user[:result]}"
puts "#{comparison_user[:name]}:#{ comparison_user[:result]}"
puts "-------------------------------"
result_of_comparison(user,comparison_user)
end
display_resultメソッドでは、make_users_informationメソッドで作成した、データを引数に受け取り、結果を表示していきます。
puts "#{item_name}"
選択した項目名を表示します
puts "#{user[:name]}:#{ user[:result]}"
マイアカウントまたは検索したユーザの
- 名前
- 選択した項目の数
を表示します。
puts "#{comparison_user[:name]}:#{ comparison_user[:result]}"
比較したいユーザの
- 名前
- 選択した項目の数
を表示します。
result_of_comparison(user,comparison_user)
最後の行で、データを比較するメソッド
result_of_comparisonメソッドを呼び出します。
def result_of_comparison(user,comparison_user)
puts user[:result] > comparison_user[:result] ? "#{ user[:name]}の方が#{user[:result]-comparison_user[:result]}多いです" : "#{ comparison_user[:name]}の方が#{comparison_user[:result]-user[:result]}多いです"
end
result_of_comparisonメソッドでは、
- マイアカウントまたは検索したユーザ
- 比較したいユーザー
の選択した項目の数を三項演算子で比較します。
user[:result] > comparison_user[:result] ?
「マイアカウントまたは検索したユーザは、比較したいユーザーより値が大きいか?」と条件を提示します。
"#{ user[:name]}の方が#{user[:result]-comparison_user[:result]}多いです" : "#{ comparison_user[:name]}の方が#{comparison_user[:result]-user[:result]}多いです"
- 真
→マイアカウントまたは検索したユーザの方が多いと出力 - 偽
→比較したユーザの方が多いと出力
となります。
まあどちらと共通して、差を求めて、どちらの方の数が多いかを求めています。以上で、メソッド部分の解説は終了になります。
フォロー&フォロワー&ツイート
こちらのトピックでは、
- フォロー
- フォロワー
- ツイート
を比較してみましょう。
上記の3つの項目を比較する際のロジック自体は、同じで、渡すデータを少し変更すれば良いだけなので、まとめて実装していきます。
if search
case num
when 1
items={search_target_user:@client.user(search_target).friends_count,comparison_user:@client.user(user_name).friends_count}
search_target_user ,comparison_user= make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"フォロー数")
when 2
items={search_target_user:@client.user(search_target).followers_count,comparison_user:@client.user(user_name).followers_count}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"フォロワー数")
when 3
items={search_target_user:@client.user(search_target).tweets_count,comparison_user:@client.user(user_name).tweets_count}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"ツイート数")
else
case num
when 1
items={myself:@client.user.friends_count,comparison_user:@client.user(user_name).friends_count}
myself ,comparison_user= make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"フォロー数")
when 2
items={myself:@client.user.followers_count,comparison_user:@client.user(user_name).followers_count}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"フォロワー数")
when 3
items={myself:@client.user.tweets_count,comparison_user:@client.user(user_name).tweets_count}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"ツイート数")
記述量が少し多いですが、実装している内容は、シンプルなので落ち着いて、ロジックを読み取りましょう。今回は、処理内容がほぼ一緒なので、フォロー数を例に解説をしていきます。
items={myself:@client.user.friends_count,comparison_user:@client.user(user_name).friends_count}
まず初めにmake_users_informationメソッドに送るデータを作成します。したがって、変数itemsにそれぞれのユーザーの比較する項目をハッシュ形式で格納します。
myself ,comparison_user= make_users_information(user_name,"analysis",items)
make_users_informationメソッドを呼び出して返り値を
- myself 0R search_target_user
- comparison_user
に格納します(分割代入)。
display_result(myself,comparison_user,"フォロー数")
最終的にdisplay_resultメソッドを呼び出して、比較結果を出力をします。この作業を他の項目でも繰り返しているだけ
です。
以上でフォロー&フォロワー&ツイートの実装を終了します。
いいね&リツイート
次のトピックでは、いいね数とリツイート数を比較する処理を実装しましょう。先程、実装した、3つの項目とは違って、Twitter::REST::Clientクラスの中に合計を簡単に求めてくれるメソッドがなかったので、一度、タイムラインの情報を全て取得して、いいね数・リツイート数を独自のメソッドを用いて合計数を求める
必要があります。
独自のメソッドで求める必要があると書きましたが、「Twitter bot 検索機能[拡張編]」で作成したTweetクラスの
- number_of_pages_judgmentメソッド
- get_all_tweetsメソッド
を軸にして実装していきます。
get_all_tweetsメソッドに以下の記述を足してください。
def get_all_tweets(user_name,pages,type )
total_repetition = 0
total_like=0
total_retweeet = 0
case type[:mode]
when "WRITE"
CSV.open("#{user_name}.csv","w") do |data|
data << ["id","投稿日","投稿内容","いいね数","リツイート数"]
pages.each do |page|
@client.user_timeline(user_name,{ count: 200 ,page:page} ).each do |timeline|
tweet = @client.status(timeline.id)
puts"--"*100
puts tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' )
puts tweet.text
puts "いいね数#{tweet.favorite_count}"
puts "リツート#{tweet.retweet_count}"
puts "--"*100
total_repetition+=1
total_like+=tweet.favorite_count
total_retweeet+=tweet.retweet_count
data << [timeline.id,tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' ),tweet.text,tweet.favorite_count,tweet.retweet_count]
end
end
puts "ツイート数#{@client.user(user_name).tweets_count}"
# puts "繰り返すた回数#{total_repetition}"
puts "トータルいいね数#{total_like}"
puts "トータルリツイート#{total_retweeet}"
data << ["", "",@client.user(user_name).tweets_count,total_like,total_retweeet]
end
when "COMPARISON"
#ここから追加
pages.each do |page|
@client.user_timeline(user_name,{ count: 200 ,page:page} ).each do |timeline|
tweet = @client.status(timeline.id)
type[:item] =="like" ? total_like+=tweet.favorite_count : total_retweeet+=tweet.retweet_count
end
end
case type[:item]
when "like"
total_like
when "retweet"
total_retweeet
else
puts "無効の値です"
end
else
puts "無効の値です"
end
追加した内容は、軽く解説しておきます。
pages.each do |page|
@client.user_timeline(user_name,{ count: 200 ,page:page} ).each do |timeline|
tweet = @client.status(timeline.id)
type[:item] =="like" ? total_like+=tweet.favorite_count : total_retweeet+=tweet.retweet_count
end
end
こちらの記述は前回の内容とほぼ一緒です。pagesという変数に格納されている、ページ数をばらして、そのブロック内で、Twitter::REST::Clientクラスのメソッドのuser_timelineメソッドを用いて、タイムライン情報を取得しています。
tweet = @client.status(timeline.id)
type[:item] =="like" ? total_like+=tweet.favorite_count : total_retweeet+=tweet.retweet_count
タイムラインID情報を、変数tweetに格納し、引数typeのitemキーのバリューが”like”だった場合は、いいね数の合計を求めます。条件に一致しない場合は、リツイート数の合計を求めます。
case type[:item]
when "like"
total_like
when "retweet"
total_retweeet
else
puts "無効の値です"
end
その後、case文を用いて、引数typeのキーのバリューの値によって条件分岐を行い、呼び出し側に返す返り値を決定
します。
- itemのバリューが”like”だった場合
→total_likeを返す - itemのバリューが”retweet”だった場合
→total_retweeetを返す
となります。
続いて、get_retweets_or_likesメソッドを作成します。
def get_retweets_or_likes(user_name,get)
pages=number_of_pages_judgment(user_name)
get_all_tweets(user_name,pages,{item: get,mode: 'COMPARISON'})
end
get_retweets_or_likesメソッドは
- number_of_pages_judgmentメソッド
- get_all_tweetsメソッド
を呼び出して、いいね数||リツイート数の合計値を求めるメソッド
です。このメソッドの返り値にいいね数| |リツイート数の合計値が返ってきます。
ここまで実装できたら、後はパズルの様に当てはめていくだけですね。以下の様にget_all_tweetsメソッドに追加しましょう。
if search
case num
when 4
comparison_user_like = get_retweets_or_likes(user_name,"like")
search_target_user_like = get_retweets_or_likes(search_target,"like")
items={search_target_user:search_target_user_like,comparison_user:comparison_user_like}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"いいね数")
when 5
comparison_user_retweet = get_retweets_or_likes(user_name,"retweet")
search_target_user_retweet = get_retweets_or_likes(search_target,"retweet")
items={search_target_user: search_target_user_retweet,comparison_user:comparison_user_retweet}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"リツイート")
else
case num
when 4
comparison_user_like = get_retweets_or_likes(user_name,"like")
myself_like = get_retweets_or_likes(nil,"like")
items={myself:myself_like,comparison_user:comparison_user_like}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"いいね数")
when 5
comparison_user_retweet = get_retweets_or_likes(user_name,"retweet")
myself_retweet = get_retweets_or_likes(nil,"retweet")
items={myself:myself_retweet,comparison_user:comparison_user_retweet}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"リツイート")
処理内容がほぼ一緒なので、いいね数を例に解説をしていきます。
comparison_user_like = get_retweets_or_likes(user_name,"like")
myself_like = get_retweets_or_likes(nil,"like")
まず初めに先程、作成したget_retweets_or_likesメソッドを用いて、それぞれいいね数の合計値を取得し、各変数に格納していきます。
items={myself:myself_like,comparison_user:comparison_user_like}
次に、make_users_informationメソッドに送るデータを作成します。なので変数itemsに先程、取得したいいね数の合計値が格納している変数をハッシュの中にセットします。
myself,comparison_user = make_users_information(user_name,"analysis",items)
make_users_informationメソッドを呼び出して返り値を
- myself 0R search_target_user
- comparison_user
に格納します(分割代入)。
display_result(myself,comparison_user,"いいね数")
最終的にdisplay_resultメソッドを呼び出して、比較した結果を出力をします。この作業を他の項目でも繰り返しているだけです。
以上でいいね&リツイートの実装を終了します。「比較に必要なメソッドを作成しよう」で作成したメソッドを使い回しているだけなので、シンプルに実装できました。メソッド間のロジックをテンプレート化すると簡単に実装できます。
検索機能と分析機能を連結させよう
分析機能は実装できたので、検索機能と連結させていきます。連結と聞くと難しく感じると思いますが、Searchクラス(検索機能)の中でAnalysisクラス(分析機能)のインスタンスを生成するだけですので、簡単に実装できます。
Searchクラスのsearch_targetメソッドの中に以下の記述を追加してください。
def search_target(user_name)
puts "#{@client.user(user_name).name}さんどの情報が知りたいですか?"
puts "[1]タイムライン"
puts "[2]フォロー数"
puts "[3]フォロワー数"
puts "[4]タイムライン情報全件取得"
puts "[5]比較する"
num = gets.to_i
case num
when 1
timeline_style(user_name)
when 2
puts "フォロー数:#{@client.user(user_name).friends_count}"
when 3
puts "フォローワー数#{client.user(user_name).followers_count}"
when 4
pages=number_of_pages_judgment(user_name)
get_all_tweets(user_name,pages,{mode: "WRITE"} )
when 5
#ここから追加
target_user = user_to_compare()
analysis = Analysis.new()
analysis.comparison_user_menu(user_name,true,target_user)
end
end
では、解説していきます。
def user_to_compare()
puts "比較したいユーザのidを入力してください。"
target_user = gets.chomp
search_account_information(target_user,true)
target_user
end
target_user = user_to_compare()
user_to_compareメソッドを呼び出して、比較したいユーザのアカウントIDを変数target_userに格納します。
analysis = Analysis.new()
Analysisクラスのインスタンスを生成します。
インスタンス生成する事でSearchクラス内で、Analysisクラスのメソッドを呼び出す事が可能になります。
analysis.comparison_user_menu(user_name,true,target_user)
Analysisクラスのcomparison_user_menuメソッドを呼び出して、「比較するメニュー欄」につなげ、連結をします。
以上で、「検索機能と分析機能を連結させよう」実装を終了し、 Twitter botの全ての実装が完了しました。なので、完成したソースコードを貼り付けておきます。
require './analysis.rb'
require 'csv'
class Search<Tweet
def initialize()
super(client)
end
def search()
puts "ユーザー名を入力してください。"
input = gets.chomp
search_account_information(input)
end
def search_target(user_name)
puts "#{@client.user(user_name).name}さんどの情報が知りたいですか?"
puts "[1]タイムライン"
puts "[2]フォロー数"
puts "[3]フォロワー数"
puts "[4]タイムライン情報全件取得"
puts "[5]比較する"
num = gets.to_i
case num
when 1
timeline_style(user_name)
when 2
puts "フォロー数:#{@client.user(user_name).friends_count}"
when 3
puts "フォローワー数#{client.user(user_name).followers_count}"
when 4
pages=number_of_pages_judgment(user_name)
get_all_tweets(user_name,pages,{mode: "WRITE"} )
when 5
target_user = user_to_compare()
analysis = Analysis.new()
analysis.comparison_user_menu(user_name,true,target_user)
end
end
def user_to_compare()
puts "比較したいユーザのidを入力してください。"
target_user = gets.chomp
search_account_information(target_user,true)
target_user
end
end
def search
search= Search.new
search.search()
end
class Analysis<Tweet
def initialize()
super(client)
end
def analysis_menu
puts "[1]タイムライン"
puts "[2]フォロー数"
puts "[3]フォロワー数"
puts "[4]タイムライン全件取得"
puts "[5]比較する"
num = gets.to_i
case num
when 1
timeline_style(@client.user.screen_name)
when 2
puts @client.user.friends_count
when 3
puts @client.user.followers_count
when 4
pages=number_of_pages_judgment(@client.user.screen_name)
get_all_tweets(nil,pages,{mode: "WRITE"} )
when 5
comparison_user_decision()
else
puts "無効の値です"
end
end
def comparison_user_decision()
puts "比較したいユーザのidを入力してください。"
user_name = gets.chomp
search_account_information(user_name,true)
comparison_user_menu(user_name)
end
def comparison_user_menu(user_name,search=false,search_target=nil)
puts "#{@client.user(user_name).name}さん"
puts "どの項目を比較しますか"
puts "[1]フォロー数"
puts "[2]フォロワー数"
puts "[3]ツイート数"
puts "[4]いいね数"
puts "[5]リツイート数"
num = gets.to_i
if search
case num
when 1
items={search_target_user:@client.user(search_target).friends_count,comparison_user:@client.user(user_name).friends_count}
search_target_user ,comparison_user= make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"フォロー数")
when 2
items={search_target_user:@client.user(search_target).followers_count,comparison_user:@client.user(user_name).followers_count}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"フォロワー数")
when 3
items={search_target_user:@client.user(search_target).tweets_count,comparison_user:@client.user(user_name).tweets_count}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"ツイート数")
when 4
comparison_user_like = get_retweets_or_likes(user_name,"like")
search_target_user_like = get_retweets_or_likes(search_target,"like")
items={search_target_user:search_target_user_like,comparison_user:comparison_user_like}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"いいね数")
when 5
comparison_user_retweet = get_retweets_or_likes(user_name,"retweet")
search_target_user_retweet = get_retweets_or_likes(search_target,"retweet")
items={search_target_user: search_target_user_retweet,comparison_user:comparison_user_retweet}
search_target_user,comparison_user = make_users_information(user_name,"search",items,search_target)
display_result(search_target_user,comparison_user,"リツイート")
else
puts "無効の値です"
end
else
case num
when 1
items={myself:@client.user.friends_count,comparison_user:@client.user(user_name).friends_count}
myself ,comparison_user= make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"フォロー数")
when 2
items={myself:@client.user.followers_count,comparison_user:@client.user(user_name).followers_count}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"フォロワー数")
when 3
items={myself:@client.user.tweets_count,comparison_user:@client.user(user_name).tweets_count}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"ツイート数")
when 4
comparison_user_like = get_retweets_or_likes(user_name,"like")
myself_like = get_retweets_or_likes(nil,"like")
items={myself:myself_like,comparison_user:comparison_user_like}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"いいね数")
when 5
comparison_user_retweet = get_retweets_or_likes(user_name,"retweet")
myself_retweet = get_retweets_or_likes(nil,"retweet")
items={myself:myself_retweet,comparison_user:comparison_user_retweet}
myself,comparison_user = make_users_information(user_name,"analysis",items)
display_result(myself,comparison_user,"リツイート")
else
puts "無効の値です"
end
end
end
def display_result(user,comparison_user,item_name)
puts "-------------------------------"
puts "#{item_name}"
puts "#{user[:name]}:#{ user[:result]}"
puts "#{comparison_user[:name]}:#{ comparison_user[:result]}"
puts "-------------------------------"
result_of_comparison(user,comparison_user)
end
def make_users_information(user_name,type,items,search_target=nil)
case type
when "analysis"
myself=
{
name:@client.user.name,
result:items[:myself]
}
comparison_user=
{
name:@client.user(user_name).name,
result:items[:comparison_user]
}
return myself , comparison_user
when "search"
searchtarget=
{
name:@client.user(search_target).name,
result:items[:search_target_user]
}
comparison_user=
{
name:@client.user(user_name).name,
result: items[:comparison_user]
}
return searchtarget,comparison_user
else
puts "無効の値です"
end
end
def result_of_comparison(user,comparison_user)
puts user[:result] > comparison_user[:result] ? "#{ user[:name]}の方が#{user[:result]-comparison_user[:result]}多いです" : "#{ comparison_user[:name]}の方が#{comparison_user[:result]-user[:result]}多いです"
end
def get_retweets_or_likes(user_name,get)
pages=number_of_pages_judgment(user_name)
get_all_tweets(user_name,pages,{item: get,mode: 'COMPARISON'})
end
end
def analysis
analysis= Analysis.new
analysis.analysis_menu
end
require "./config.rb"
require "json"
require "open-uri"
require "csv"
require "./weather_class.rb"
require "./tweet.rb"
require "./search.rb"
require "./analysis.rb"
def execution
puts "メニューを選択してください"
puts "[1]天気予報を取得してツイートする"
puts "[2]5日間の天気情報を表示"
puts "[3]プロフィール編集"
puts "[4]ユーザ検索"
puts "[5]自己分析"
num = gets.to_i
case num
when 1
current_time_weather = wetaher(num)
tweet(current_time_weather,num)
when 2
current_time_weather = wetaher(num)
when 3
tweet(current_time_weather,num)
when 4
search()
when 5
analysis()
else
puts "無効な値です"
end
end
execution()
require 'date'
require 'csv'
class Wetaher
def initialize(citys)
@citys=citys
end
def select_city
@citys.each do |city|
puts "#{city['id']}:#{city['city']}"
end
# puts "天気予報を確認したい都市を選択してください"
puts "天気情報を取得したい都市を選択してください"
input = gets.to_i-1
@citys[input]
end
def get_weather_forecast(city)
response = open(WEATHER_URL + "?q=#{city['english']}&appid=#{WEATHER_API_KEY}&units=metric&lang=ja")
data=JSON.parse(response.read)
json_to_parse(data['list'])
datas= {list: data['list'],city_name:data['city']['name']}
end
def display_weather_forecast(weathers)
CSV.open("#{weathers[:city_name]}.csv","w") do |data|
data<<["id","時間","天気","気温"]
puts "地区:#{weathers[:city_name]}"
id = 0
weathers[:list].each do|weather|
id+=1
puts "------------------------------"
puts "時間#{weather['dt_txt']}"
puts "天気:#{weather['weather'][0]['description']}"
puts "気温:#{weather['main']['temp']}℃"
puts "------------------------------"
data<<[id,Time.parse(weather['dt_txt']).strftime('%Y年%m月%d日 %H時%M分' ),weather['weather'][0]['description'],weather['main']['temp']]
end
end
end
def json_to_parse(weathers)
weather=JSON.pretty_generate(weathers)
File.open("tenki.json", mode = "w"){|f|
f.write(weather)
}
end
def display_weather_text(weathers)
File.open("tenki.txt", mode = "w"){|f|
f.write(
weathers[:list].each do|weather|
puts "------------------------------"
puts "時間#{weather['dt_txt']}"
puts "天気:#{weather['weather'][0]['description']}"
puts "気温:#{weather['main']['temp']}℃"
puts "------------------------------"
end
)
}
end
def current_time_weather(wethers)
wethers[:list].map{|wether|wether['dt_txt']= Time.parse(wether['dt_txt'])}
current_weather = wethers[:list].select{|wether|wether['dt_txt']>=Time.now}.first
dt_txt = current_weather['dt_txt'].strftime('%Y年%m月%d日 %H時%M分%S秒' )
data = {
city:wethers[:city_name] ,
dt_txt: dt_txt,
description:current_weather['weather'][0]['description'],
temperature: current_weather['main']['temp'],
icon:current_weather['weather'][0]['icon']
}
end
end
def wetaher(num)
citys=CSV.read("./citys.csv",headers: true)
wether = Wetaher.new(citys)
city=wether.select_city
datas=wether.get_weather_forecast(city)
case num
when 1
wether.current_time_weather(datas)
when 2
wether.display_weather_forecast(datas)
end
end
require 'twitter'
require './config.rb'
require 'csv'
class Tweet
attr_accessor :client
def initialize(current_time_weather)
@client = Twitter::REST::Client.new do |config|
config.consumer_key = CONSUMER_KEY
config.consumer_secret = CONSUMER_SECRET
config.access_token = ACCESS_TOKEN
config.access_token_secret = ACCESS_TOKEN_SECRET
end
@current_time_weather = current_time_weather
end
def updata
text = "#{@current_time_weather[:dt_txt]}\n#{@current_time_weather[:city]}の天気\n天気:#{@current_time_weather[:description]}\n気温:#{@current_time_weather[:temperature]}"
@client.update(text)
end
def account_setting
puts "アカウント名:#{@client.user.name}"
puts "プロフィール文\n#{@client.user.description }"
puts "[1]アカウント名を変更する"
puts "[2]プロフィール文を変更する"
puts "[3]閉じる"
num = gets.to_i
case num
when 1
name =gets.chomp
@client.update_profile({name:name} )
when 2
description = gets.chomp
@client.update_profile({description:description} )
when 3
return
end
end
def search_account_information(user_name,analsis=false)
puts @client.user(user_name).screen_name # アカウントID
puts @client.user(user_name).name # アカウント名
puts @client.user(user_name).description # プロフィール
puts "こちらのアカウントのでお間違い無いですか?"
puts "[1]YES"
puts "[2]NO"
num = gets.to_i
case num
when 1
if analsis
nil
else
search_target(user_name)
end
when 2
return
else
puts"無効な値です"
end
end
def timeline_style(user_name)
puts "CSVファイルにデータを書き込みますか❓"
puts "[1]YES"
puts "[2]NO"
num = gets.to_i
case num
when 1
timeline_write(user_name)
when 2
timeline(user_name)
else
puts "無効の値です"
end
end
def timeline(user_name,write=false)
total_repetition = 0
likes = 0
retweets = 0
data=[] if write
@client.user_timeline(user_name).each do |tweet|
puts "---------------------------------------------"
puts "更新日#{tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' )}"
puts tweet.full_text
puts "いいね数:#{tweet.favorite_count}"
puts "リツイート数:#{tweet.retweet_count}"
puts "---------------------------------------------"
likes += tweet.favorite_count
retweets +=tweet.retweet_count
total_repetition +=1
data << [ total_repetition,tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' ),tweet.text,tweet.favorite_count.to_i,tweet.retweet_count] if write
end
puts "ツイート数:#{ total_repetition}"
puts "トータルいいね数:#{likes}"
puts "トータルリツイート数:#{retweets}"
data if write
end
def timeline_write(user_name)
puts "ss"
CSV.open("#{user_name}timeline.csv","w") do |data|
data << ["id","投稿日","投稿内容","いいね数","リツイート数"]
tweets=timeline(user_name,true)
tweets.each do |tweet|
data<<tweet
end
end
end
def get_all_tweets(user_name,pages,type )
total_repetition = 0
total_like=0
total_retweeet = 0
case type[:mode]
when "WRITE"
CSV.open("#{user_name}.csv","w") do |data|
data << ["id","投稿日","投稿内容","いいね数","リツイート数"]
pages.each do |page|
@client.user_timeline(user_name,{ count: 200 ,page:page} ).each do |timeline|
tweet = @client.status(timeline.id)
puts"--"*100
puts tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' )
puts tweet.text
puts "いいね数#{tweet.favorite_count}"
puts "リツート#{tweet.retweet_count}"
puts "--"*100
total_repetition+=1
total_like+=tweet.favorite_count
total_retweeet+=tweet.retweet_count
data << [timeline.id,tweet.created_at.getlocal.strftime('%Y年%m月%d日 %H時%M分%S秒' ),tweet.text,tweet.favorite_count,tweet.retweet_count]
end
end
puts "ツイート数#{@client.user(user_name).tweets_count}"
puts "トータルいいね数#{total_like}"
puts "トータルリツイート#{total_retweeet}"
data << ["", "",@client.user(user_name).tweets_count,total_like,total_retweeet]
end
when "COMPARISON"
pages.each do |page|
@client.user_timeline(user_name,{ count: 200 ,page:page} ).each do |timeline|
tweet = @client.status(timeline.id)
type[:item] =="like" ? total_like+=tweet.favorite_count : total_retweeet+=tweet.retweet_count
end
end
case type[:item]
when "like"
total_like
when "retweet"
total_retweeet
else
puts "無効の値です"
end
else
puts "無効の値です"
end
end
def number_of_pages_judgment(user_name)
pages =[]
if @client.user(user_name).tweets_count < 200
count = 1
elsif @client.user(user_name).tweets_count % 200==0
count = @client.user(user_name).tweets_count / 200
else
remainder = (@client.user(user_name).tweets_count / 200)
count = remainder+1
remainder_num=@client.user(user_name).tweets_count-200*remainder
end
1.upto(count) do |num|
pages.push(num)
end
pages
end
end
def tweet(current_time_weather,num)
tweet = Tweet.new(current_time_weather)
case num
when 1
tweet.updata()
puts "ツイートが完了しました。"
when 3
tweet.account_setting()
else
puts "無効の値です"
end
end
WEATHER_API_KEY = ENV['WEATHER_API_KEY']
WEATHER_URL = ENV['WEATHER_URL']
CONSUMER_KEY = ENV['CONSUMER_KEY']
CONSUMER_SECRET = ENV['CONSUMER_SECRET']
ACCESS_TOKEN = ENV['ACCESS_TOKEN']
ACCESS_TOKEN_SECRET = ENV['ACCESS_TOKEN_SECRET']
id,city,english
1,東京都,Tokyo
2,大阪,Osaka
3,沖縄,Okinawa
4,北海道,Hokkaido
まとめ:Twitter bot 分析機能[拡張編]
今回でTwitter botシリーズは終了になります。作成したTwitter botは大まかに、
- ツイート機能(天気情報)
- プロフィール編集機能
- 検索機能
- 分析機能
と上記の4つの機能を実装していきました。更に実用的なTwitter botになりました。皆さんもオリジナルなTwitter botを作成してみましょう。
以上、kazutoでした。
関連記事
※この記事は、下記の4つの記事をご覧いただき、天気予報botを作成してから読み始めていきましょう。
- 天気予報APIを用いて5日間の天気情報を取得しよう
- TwitterのAPIを使った天気予報botを作成してみよう
- Twitter bot プロフィール設定[拡張編]
- Twitter bot 検索機能[拡張編]