Advertisement
Guest User

Untitled

a guest
Aug 15th, 2022
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.27 KB | None | 0 0
  1. require 'net/http'
  2. require 'uri'
  3. require 'json'
  4. require 'csv'
  5. require 'pry'
  6. require 'time'
  7.  
  8. API_KEY = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" # YoutubeDataAPIのAPI_KEY
  9. CHANNEL_ID = "UCi88-cFh7m3FKg3rlkEBv_g" # 投稿者のチャンネルID
  10. MAX_RESULT = 50 # 一度に取得できる動画の情報の数は50まで
  11.  
  12. @video_infos = []
  13.  
  14. # 引数の日時より前に投稿された動画の情報を取得しハッシュで返す
  15. def get_json(published_before)
  16. base_url = "https://www.googleapis.com/youtube/v3/search?key=#{API_KEY}&channelId=#{CHANNEL_ID}&part=snippet&order=date&maxResults=#{MAX_RESULT}&publishedBefore="
  17. url = base_url + published_before
  18. uri = URI.parse(url)
  19. http = Net::HTTP.new(uri.host, uri.port)
  20. json = Net::HTTP.get(uri)
  21. result = JSON.parse(json)
  22. result
  23. end
  24.  
  25. def rfc3339_to_date(rfc3339)
  26. time = rfc3339.scan(/\d+/)
  27. Time.parse("#{time[0]}-#{time[1]}-#{time[2]} #{time[3]}:#{time[4]}:#{time[5]}")
  28. end
  29.  
  30. def date_to_rfc3339(date)
  31. date.utc.strftime('%FT%TZ')
  32. end
  33.  
  34. # 一度のリクエストで最大50件しか動画の情報を取得できないので、publishedBefore パラメーターに
  35. # 取得した最後の動画の投稿日+1秒を代入し、それ以前の動画を50件取得する。これを再帰関数で繰り返す
  36. def retrieve_data(published_before)
  37. data = get_json(published_before)
  38.  
  39. if data.dig('error', 'errors', 0, 'reason') == 'quotaExceeded'
  40. puts "アクセスできる回数を超えています。24時間お待ちください"
  41. exit
  42. end
  43.  
  44. # ベースケースの処理。Youtubeの仕様でresultsPerPage==0 は動画を全て取得したときのサイン
  45. if data['pageInfo']['resultsPerPage'] == 0
  46. puts "動画の情報の収集が完了しました"
  47. return
  48. end
  49.  
  50. data['items'].each do |video|
  51. title = video['snippet']['title']
  52. uploader = video['snippet']['channelTitle']
  53. video_id = video['id']['videoId']
  54. video_url = "https://www.youtube.com/watch?v=#{video_id}"
  55. thumbnails = video['snippet']['thumbnails']['high']['url']
  56. published_at = video['snippet']['publishedAt']
  57.  
  58. if video_id.nil?
  59. if video['id']['kind'] == "youtube#video"
  60. puts "非公開の動画なのでスキップ"
  61. next
  62. end
  63. if video['id']['kind'] == "youtube#channel"
  64. puts "チャンネル情報なのでスキップ"
  65. next
  66. end
  67. end
  68.  
  69. video_info = {title: title, uploader: uploader, video_url: video_url, thumbnails: thumbnails, published_at: published_at}
  70. @video_infos.push(video_info)
  71. end
  72.  
  73. oldest_published_at = rfc3339_to_date(@video_infos.last[:published_at]) # rfc3339はStringなので時間操作するためにTime型に変更
  74. next_designated_time = date_to_rfc3339(oldest_published_at + 1) # 投稿時間+1秒に指定することで現在の動画を検索結果に含まない
  75. retrieve_data(next_designated_time)
  76. end
  77.  
  78. now = date_to_rfc3339(Time.now) # 日時のフォーマットはRFC3339形式
  79. retrieve_data(now)
  80.  
  81. File.open("youtube-list.json", "w") do |f|
  82. JSON.dump(@video_infos, f)
  83. end
  84.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement