James Scott James Scott - 1 month ago 7
Ruby Question

How to get many JSON URLs and parse for dynamic content

I'm trying to create a first app that parses data from TMDB's API.

When I try to load and parse one URL everything works fine:

uri = URI.parse("http://api.themoviedb.org/3/tv/#URI.escape(@id)}?api_key=#{@api_key}")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
@results = JSON.load(response.body)


But now I want to parse JSON available at:

/tv/{tv_id}/season/{season_number}/episode/{episode_number}


Where:
{tv_id}
is
@id = params[:id]


{season_number}
and
{episode_number}
are seasons and episodes resulting from the the first URL.
I tried multiple ways but I get a random error each time.

The full code is on Github.
The working app is TOMDB App on Heroku.

I'm trying to display the season title and episodes in the same page with Serie.
For example, when I parse:

https://api.themoviedb.org/3/tv/2432?api_key=**********


I get:

{
"backdrop_path":"/hl9mC6fc2adfeGpI1ijKCfQ0KzI.jpg",
"name":"Taken",
"number_of_episodes":10,
"number_of_seasons":1
}


So I have 10 episodes for one season. For each episode I have an URL by replacing the episode number
{1..5..10}
to:

https://api.themoviedb.org/3/tv/8681/season/1/episode/*1*?api_key=********


I want to display episodes name for each one, so the JSON result for one episode is like:

{
"name":"Beyond the Sky","overview":"......",
"id":183273,
"vote_average":0.0,
"vote_count":0
}

Answer

You need to use https for that request, see the parts I marked with #** that need to be changed. Remark the use of Net::HTTP.start instead of Net::HTTP.new. Nice app by the way.

require 'net/http'
require 'net/https' #*add*
require 'json'
require 'open-uri'

url = 'https://api.themoviedb.org/3/tv/1418/season/1/episode/1?api_key=**************************&language=en-US'
uri = URI.parse(url)
# *adapt following line*
http = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', :verify_mode => OpenSSL::SSL::VERIFY_NONE)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
json = JSON.load(response.body)


# {"air_date"=>"2007-09-24", "crew"=>[{"id"=>157437, "credit_id"=>"5256cfee19c2956ff60a280c", "name"=>"James Burrows", "department"=>"Directing", "job"=>"Director", "profile_path"=>"/lTcRumFOm6HkfOyPuUElV4l4n4r.jpg"}, {"id"=>160172, "credit_id"=>"5256cfbc19c2956ff60a0483", "name"=>"Chuck Lorre", "department"=>"Writing", "job"=>"Writer", "profile_path"=>"/btpYlMV71sjQXrV142I9kogEINI.jpg"}, {"id"=>163528, "credit_id"=>"5256cfbd19c2956ff60a04f0", "name"=>"Bill Prady", "department"=>"Writing", "job"=>"Writer", "profile_path"=>"/duXUvo8JtivQR0BHiXHGQwoNYB4.jpg"}, {"id"=>1480308, "credit_id"=>"55881d379251416818001c2b", "name"=>"Janice Zoladz", "department"=>"Costume & Make-Up", "job"=>"Hairstylist", "profile_path"=>nil}, {"id"=>1480289, "credit_id"=>"558819ffc3a36836ea006145", "name"=>"Joe Bella", "department"=>"Production", "job"=>"Co-Producer", "profile_path"=>nil}, {"id"=>1232374, "credit_id"=>"55881a1492514179f6003f6e", "name"=>"Michael Collier", "department"=>"Production", "job"=>"Producer", "profile_path"=>nil}, {"id"=>1480291, "credit_id"=>"55881a269251411efc000f6e", "name"=>"Toti Levine", "department"=>"Production", "job"=>"Associate Producer", "profile_path"=>nil}], "episode_number"=>1, "guest_stars"=>[{"id"=>1118085, "name"=>"Brian Patrick Wade", "credit_id"=>"5256cfc919c2956ff60a0c8f", "character"=>"Kurt", "order"=>0, "profile_path"=>"/6y0Hd1xLC5Nitedg2GQ90DtxxDb.jpg"}, {"id"=>157085, "name"=>"Vernee Watson-Johnson", "credit_id"=>"5256cfd719c2956ff60a1747", "character"=>"", "order"=>1, "profile_path"=>"/dRXXPoeAAbl1PhURCJfKCDoZiUn.jpg"}], "name"=>"Pilot", "overview"=>"Brilliant physicist roommates Leonard and Sheldon meet their new neighbor Penny, who begins showing them that as much as they know about science, they know little about actual living.", "id"=>64766, "production_code"=>nil, "season_number"=>1, "still_path"=>"/rxWlBXZhGWhumbLB8gAHyyW3ITD.jpg", "vote_average"=>7.39285714285714, "vote_count"=>14}

EDIT: to get all the episodes from a season you just have to count from 1 to the number of episodes and assemble and request the new url. You would have to do the same to enumerate all seasons of a series but I left you some work over 8:) Success !

require 'net/http'
require 'net/https'
require 'json'
require 'open-uri'
require 'pp'

# we have to do this more than once, so let's make it DRY
def get_json url
  uri = URI.parse(url)
  http = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', :verify_mode => OpenSSL::SSL::VERIFY_NONE) #**
  request = Net::HTTP::Get.new(uri.request_uri)
  response = http.request(request)
  JSON.load(response.body)
end

API_KEY  = '****************************'
url = "https://api.themoviedb.org/3/tv/2432?api_key=#{API_KEY}"
season = get_json url

season['number_of_episodes'].to_i.times do |episode|
  episode += 1 # times starts from 0 , so we add 1
  url = "https://api.themoviedb.org/3/tv/8681/season/1/episode/#{episode}?api_key=#{API_KEY}"
  episode = get_json url
  # pp episode
  puts episode['name']
end

gives

# Great White Shark: The True Story of Jaws
# Polar Bear: The Arctic Warrior
# Crocodile: The Smiling Predator
# Leopard: The Agent of Darkness
# Eagle: The Master of the Skies
# Humpback Whale: The Giant of the Oceans
# Wolf: The Legendary Outlaw
# Tiger: The Elusive Princess
# Lions: Spy in the Den
# Grizzly: Face to Face
Comments