Facebook
From Sweltering Parakeet, 3 Years ago, written in Ruby (with Ruby on Rails Framework).
Embed
Download Paste or View Raw
Hits: 417
  1. # プログラミング言語はRubyなのでパソコンにRubyをインストールしてね
  2.  
  3. # このファイルを実行したら youtube-info.csv ってファイルができるからエクセルなどで開いて
  4.  
  5. # タイトル、動画リンク、サムネリンクなどを簡単に表にまとめられるよ
  6.  
  7. # !!注意!!!!!!!!!
  8. # このままだと動きません!!
  9. # YoutubeAPI を用意する必要があるので
  10. # https://hi3103.net/notes/web/1271
  11. # このサイトの手順でAPIっていう英数字の羅列を取得してください。
  12. # その後、下のAPI_KEY = "" の ""の中に入力してください
  13. # (例) API_KEY = "ABCDEF123451hW4RU7a0YXMrUUUAAAAqwer_AAAA"
  14.  
  15. API_KEY = ""
  16.  
  17. CHANNEL_ID = "UCi88-cFh7m3FKg3rlkEBv_g" # 投稿者のチャンネルID。デフォルトは尊師のチャンネル
  18. MAX_RESULT = 50
  19.  
  20. require 'net/http'
  21. require 'uri'
  22. require 'json'
  23. require 'csv'
  24. require 'pry'
  25. require 'time'
  26.  
  27. @video_infos = []
  28.  
  29. # 引数の日時より前に投稿された動画の情報を取得しハッシュで返す
  30. def get_json(published_before)
  31.     base_url = "https://www.googleapis.com/youtube/v3/search?key=#{API_KEY}&channelId=#{CHANNEL_ID}&part=snippet&order=date&maxResults=#{MAX_RESULT}&publishedBefore="
  32.     url = base_url + published_before
  33.     uri = URI.parse(url)
  34.     http = Net::HTTP.new(uri.host, uri.port)
  35.     json = Net::HTTP.get(uri)
  36.     result = JSON.parse(json)
  37.     result
  38. end
  39.  
  40. def rfc3339_to_date(rfc3339)
  41.     time = rfc3339.scan(/\d+/)
  42.     Time.parse("#{time[0]}-#{time[1]}-#{time[2]} #{time[3]}:#{time[4]}:#{time[5]}")
  43. end
  44.  
  45.  
  46. # 一度のリクエストで最大50件しか動画の情報を取得できないので、publishedBefore パラメーターに
  47. # 取得した最後の動画の投稿日を代入し、それ以前の動画を50件取得する。これを再帰関数で繰り返す
  48. def retrieve_data(published_before)
  49.     data = get_json(published_before)
  50.    
  51.     if data.dig('error', 'errors', 0, 'reason') == 'quotaExceeded'
  52.         puts "アクセスできる回数を超えています。しばらくしてから試してください"
  53.         exit
  54.     end
  55.  
  56.     # ベースケースの処理。Youtubeの仕様でresultsPerPageが0になったときが動画を全て取得したときのサイン
  57.     if data['pageInfo']['resultsPerPage'] == 0
  58.         return
  59.     end
  60.    
  61.     data['items'].each do |video|
  62.         title        = video['snippet']['title']
  63.         uploader     = video['snippet']['channelTitle']
  64.         video_id     = video['id']['videoId']
  65.         video_url    = "https://www.youtube.com/watch?v=#{video_id}"
  66.         thumbnails   = video['snippet']['thumbnails']['high']['url']
  67.         published_at = video['snippet']['publishedAt']
  68.  
  69.         # video_id.nil? だけなら非公開の動画なのか投稿者の情報なのかがわからない。
  70.         if video_id.nil?
  71.             if video['id']['kind'] == "youtube#video"
  72.                 puts "非公開の動画なのでスキップ"
  73.                 next
  74.             end
  75.             if video['id']['kind'] == "youtube#channel"
  76.                 puts "チャンネル情報なのでスキップ"
  77.                 next
  78.             end
  79.         end
  80.  
  81.         video_info   = {title: title, video_url: video_url, thumbnails: thumbnails, published_at: published_at}
  82.         @video_infos.push(video_info)
  83.     end
  84.    
  85.     oldest_published_at = rfc3339_to_date(@video_infos.last[:published_at])
  86.     next_published_at = (oldest_published_at + 1).utc.strftime('%FT%TZ')
  87.     retrieve_data(next_published_at)
  88. end
  89.  
  90. now = Time.now.utc.strftime('%FT%TZ') # 日時のフォーマットはRFC3339形式
  91. retrieve_data(now)
  92.  
  93. CSV.open("youtube-info.csv", "w") do |csv|
  94.     header = @video_infos[0].keys.map { |k| k.to_s}
  95.     @video_infos.each do |video_info|
  96.         csv << video_info.values
  97.     end
  98. end
  99.  
  100. puts "動画情報をCSVでまとめたよ!"