LoginSignup
9

More than 5 years have passed since last update.

posted at

updated at

Twitterのいいね(ふぁぼ)を検索したい

はじめに

こんばんわ,高知工科大学AdventCalendar2017の22日目を担当させていただくTokikaze0604です.
これ書いてる現在12月22日22時前です,すいません.
(途中でブラウザバックが暴発して記事が消えてくたばりかけました,つらい)
今回は,個人的に欲しいなーと思っている,自分のいいね(ふぁぼ)を検索できる何かを作ることにしました.
何か良いアプリとかあったら教えてください.

できたものは一応Githubに置きました.(2017/12/22現在:クローンしてもElasticsearchのgem入れるところで失敗するので,早めに直します. )
2018/01/26追記:去年のうちに修正していたのですが,記事の更新を忘れていました.現在は正常に動作します.

使ったもの

  • TwitterAPI
  • Ruby
  • Ruby on Rails (5)
  • Elasticsearch

別にElasticsearchを使うのはmustではなかったのですが,全然最近(?)の技術を触っていない(最近Promelaしか触ってない)ので,何か使ってみたかったので試しに使ってみました.
それに加えて,いい感じに検索してくれるらしいので,そっちも試しに.

やること

  1. ツイッターからいいね(ふぁぼ)を全件取得する
  2. Elasticsearchに入れる
  3. Railsで適当にページ作って表示

大したことはできまsしません.

手順1:ツイッターからいいね(ふぁぼ)を全件取得する

特に面白くもないいいね(ふぁぼ)を取得するRubyのコード.
twitterのgem使ってます.

@client = Twitter::REST::Client.new do |config|
  config.consumer_key = ENV['CONSUMER_KEY']
  config.consumer_secret = ENV['CONSUMER_SECRET']
  config.access_token = ENV['ACCESS_TOKEN']
  config.access_token_secret = ENV['ACCESS_TOKEN_SECRET']
end

def get_favs(n = 200, max_id)
  @client.favorites(:count => n, :max_id => max_id)
end

max_idにツイートのID渡すと,そのID以下のツイートがcount件返ってきます.
最後に取得したツイートのIDをそのまま渡すと1件重複するするので,下のように-1を入れるようにします.
参考

res = get_favs(max_id) # max_id以下のidのふぁぼ(ツイート)を取得
res.map do |status|
  count = count + 1
  max_id = status.id - 1
  append_fav(favs, status, count) # ふぁぼをハッシュに格納する
end

そんな感じで取得してみると....
スクリーンショット 2017-12-22 22.17.51.png

もっとあるはずなのに,3154件で終わってしまいました.
スクリーンショット 2017-12-22 22.14.25.png
最後に取得したいいね(ふぁぼ)が約2ヶ月前なので,2ヶ月が限界なのでしょうか.
ぐぐる力が足りなくて調べきれなかったのですが,もしかして課金APIなら全件取得できる...?

手順2:Elasticsearchに入れる

準備不足で時間が仕方ないので2ヶ月分で我慢してElasticsearchに移ります.

こちらの記事を参考にElasticserachを導入しました.

ただ,elasticsearch-headはElasticsearch5.XXからpluginで入れられなくなったらしいので,別記事を参考に導入しました.

詳しいの説明は省きますが,localhost:9200にアクセスして以下のような感じなら勝ちです.
スクリーンショット 2017-12-22 22.47.51.png

次は取得したいいね(ふぁぼ)をElasticsearchにぶち込む過程ですが,
これはもうRailsでやってしまいます.

こちらの記事を参考に,scaffoldで適当に(ちょうど良いという意味だといいな)動くものを作ります.

ツイートのIDは18桁の数値なので,decimalで取りました.
decimal使う時はシングルクォーテーションで囲まないとおかしなことになるらしいです.
参考

$ rails new fav
$ cd fav
$ rake db:create
$ bundle exec rails g scaffold favorite 'tweet_id:decimal{18,0}' text:text user_name:string created_at:date
$ bundle exec rake db:migrate

ここまででとりあえずRailsの方ができたので次はElasticsearchのgemを入れて,Elasticsearch用の設定とかを書いていきます.
詳しい部分は参考記事に任せることにして(ほとんどArticleをFavoriteに変えるだけ),
大きく異なる部分のみをご紹介します.

まずは,マッピング情報の設定です.
参考記事では以下のように文字列のマッピングにstringを設定していますが,

# app/models/concerns/article_searcable.rb
...
# マッピング情報
    settings do
      mappings dynamic: 'false' do # 動的にマッピングを生成しない
        indexes :title, analyzer: 'kuromoji', type: 'string'
        indexes :body,  analyzer: 'kuromoji', type: 'string'
      end
    end
...

Elasticsearch6.XXからはtextと設定するようになったようです.
参考

それから,今回は必要ないのですが,何度もツイートを取得・保存することを考えて重複しないようにしました.
参考

# app/models/favorite.rb
class Favorite < ApplicationRecord
  include FavoriteSearchable
  validates :tweet_id, :uniqueness => {:scope => :text} # ここで重複を制限
end
# db/migrate/20171221141005_create_favorites.rb
class CreateFavorites < ActiveRecord::Migration[5.1]
  def change
    create_table :favorites do |t|
      t.decimal :tweet_id, precision: 18, scale: 0
      t.text :text
      t.string :user_name
      t.time :created_at

      t.timestamps
    end
    add_index :favorites, [:tweet_id, :text], unique: true # ここで重複を制限
  end
end

手順3:Railsで適当にページ作って表示

最後はViewをいじるのですが,とりあえず検索できれば満足なのでツイッターのリンクを貼るだけにとどめます.
手順にするほどじゃない

# app/views/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Favorites</h1>

<%= form_tag favorites_path, :method => :get do %>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag 'Search', :name => nil %>
<% end %>
...

完成

そんな感じで色々と雑完成しました.
rails sでサーバを立てて,'localhost:3000/favorites'にアクセスすると以下のように表示されます.

スクリーンショット 2017-12-22 23.16.04.png

検索するとこんな感じです.
スクリーンショット 2017-12-22 23.18.00.png

何も考えずに本文とユーザ名の両方にマッピングしたので,ユーザ名に検索ワードが入っている人が出てきて見辛い....
(そもそも見た目がひどい)

おわりに

そんなこんなで色々と期待通りの結果は得られませんでしたが,久しぶりにコードを見たり書いたりしたので楽しかったです.
全然Elasticsearchを活かせていないのは確実なので,もうちょっとブラッシュアップしていきたいと思います.
(とりあえずGithubからクローンしても動くようにします...)

稚拙な技術と文章ですが,ここまで読んでくださりありがとうございました.
(次の機会があればもっと余裕を持って投稿します,ごめんなさい)

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
What you can do with signing up
9