からっぽのしょこ

読んだら書く!書いたら読む!読書読読書読書♪同じ事は二度調べ(たく)ない

Rでツイート画像を取得する

はじめに

 rtweetパッケージを使って、特定の単語と共にツイートされた画像を抽出して保存します。

【他のネタ一覧】

www.anarchive-beta.com

【目次】


・ツイート画像を取得する

# 利用パッケージ
library(rtweet) # ツイートの取得:search_tweets()
library(magick) # 画像の取得:image_read(), image_write()
library(dplyr) # データ操作
library(tidyr) # unnest()

 利用するパッケージを読み込みます。

・ツイートの収集

 まずはrtweetパッケージを利用して、ツイートを集めます。

# 検索ワードを指定してツイートを取得
tw_data <- search_tweets("#鞘師里保誕生祭", n = 1000, include_rts = FALSE)

 search_tweets()に検索ワードを指定してツイートを拾ってきます。引数nには取得するツイート数を指定します。include_rts = FALSEで、リツイートを除くことができます(デフォルトはTRUE)。

 取得したツイートデータから、画像のURLを抽出します。URL情報はext_media_url列です。

# 画像のurlを抽出
tw_pic_url <- tw_data %>% 
  unnest(ext_media_url) %>% # 画像urlのネストを解除
  filter(!is.na(ext_media_url)) %>%  # 画像を含むもののみ抽出
  select(created_at, screen_name, text, ext_media_url)

 1つのツイートに複数枚の画像が含まれる場合はURLがネスト(入れ子)されているので、unnest()で解除します。

 逆に画像がないツイートはNAとなっているので、filter()NAでないもののみ取り出します。

 最後に必要な情報を取り出します。必要なのはext_media_urlだけですが、重複等の確認のためにここではツイート日時・ユーザーネーム・ツイートテキストも取り出すことにします。

tail(tw_pic_url, 10)
## # A tibble: 10 x 3
##    created_at          text                       ext_media_url                 
##    <dttm>              <chr>                      <chr>                         
##  1 2020-05-27 15:00:11 "鞘師里保ちゃん\n22歳の誕生日おめでとう\U0~ http://pbs.twimg.com/media/EZ~
##  2 2020-05-27 15:00:10 "誕生日おめでとう!!\n一生大好きです!\nイン~ http://pbs.twimg.com/media/EZ~
##  3 2020-05-27 15:00:10 "誕生日おめでとう!!\n一生大好きです!\nイン~ http://pbs.twimg.com/media/EZ~
##  4 2020-05-27 15:00:10 "誕生日おめでとう!!\n一生大好きです!\nイン~ http://pbs.twimg.com/media/EZ~
##  5 2020-05-27 15:00:10 "誕生日おめでとう!!\n一生大好きです!\nイン~ http://pbs.twimg.com/media/EZ~
##  6 2020-05-27 15:00:08 "鞘師里保ちゃんHAPPY BIRTHDAY<U+2764><U+FE0F>\~ http://pbs.twimg.com/media/EZ~
##  7 2020-05-27 15:00:05 "#鞘師里保 #鞘師里保誕生祭\nりほりほお誕生日~ http://pbs.twimg.com/media/EZ~
##  8 2020-05-27 15:00:03 "鞘師里保ちゃん22歳のお誕生日おめでとう\U00~ http://pbs.twimg.com/media/EZ~
##  9 2020-05-27 15:00:02 "鞘師里保ちゃんお誕生日おめでとう\U0001f3~ http://pbs.twimg.com/media/EZ~
## 10 2020-05-27 13:09:12 "もう直ぐりほりほお誕生日だよー!\nみんなでお祝~ http://pbs.twimg.com/ext_tw_v~

 (ユーザーネームの情報は落としています。)ツイート日時は協定世界時なので、日本時間とはズレています。またネストを解除した影響で、画像枚数分複製されているものがあります。

 問題がなければ、このURLから画像を保存していきます。

・画像の取得

 続いてmagickパッケージを利用して、画像を取得します。

# 画像を取得
for(i in 1:nrow(tw_pic_url)) {
  
  # urlを取り出す
  pic_url <- tw_pic_url[["ext_media_url"]][i]
  
  # 画像を取得
  pic_data <- image_read(pic_url)
  
  # 画像を保存
  image_write(pic_data, path = paste0("pic_data/rihoriho/rihoriho_", i, ".png"), format = "png")
  
  # おまじない
  Sys.sleep(1)
}

 for()ループで、順番に画像を取得し保存します。

 URLを1つ取り出してimage_read()に渡し、画像を取得します。

 取得した画像データをimage_write()で書き出します。ファイル名と拡張子も付けてファイルパスを指定します。

 サーバーに負荷がかかりすぎないように、Sys.sleep()で処理を一時停止しましょう。

 指定したフォルダに画像が1つずつ保存されていきます。

複数単語分のツイートを取得した場合

 例えば誕生日をお祝いするツイートをするときにハッシュタグ「○○誕生祭」あるいは「○○生誕祭」を付けますよね?さてどちらも集めたいわけですが、単純に2単語でツイート取得してデータ結合すると、両方の単語を含むツイートは重複してしまいます。

# 誕生祭・生誕祭ツイートを取得
tw_data_tanjoh <- search_tweets("#鞘師里保誕生祭", n = 1000, include_rts = FALSE)
tw_data_seitan <- search_tweets("#鞘師里保誕生祭", n = 1000, include_rts = FALSE)

# 結合
tw_data <- rbind(tw_data_tanjoh, tw_data_seitan)


 そんなときは、status_id列がツイートごとに振られる固有のIDなので、dplyr::distinct()で重複する行を落とせます。引数の.keep_allがデフォルトのFALSEだと指定した列以外の列を落としてしまうので、TRUEを指定しておきましょう。

# 画像のurlを抽出
tw_pic_url <- tw_data %>% 
  select(status_id, created_at, screen_name, text, hashtags, ext_media_url) %>% # 必要な列を抽出
  distinct(status_id, .keep_all = TRUE) %>% # 重複を削除
  unnest(ext_media_url) %>% # 画像urlのネストを解除
  filter(!is.na(ext_media_url)) # 画像のあるもののみ抽出


 他の処理は一緒のはずです。(追記しました!)

おわりに

 ご利用は程々にしましょう。程々なら問題ないですよね??

 規約違反だったりするのなら教えてください。お願いします。

2020.05.28:元モーニング娘。鞘師りほりほ!22歳のお誕生日!!!おめでとうございます。