为什么我得到“没有将String隐式转换为Integer(TypeError)”?

我有一些代码,我在非常类似的情况下运行。 这是第一个情况,我有一部电影的imdb_id我想要的细节:

 url = "http://mymovieapi.com/?id=#{self.imdb_id}&type=json&plot=none&episode=0&lang=en-US&aka=simple&release=simple&business=0&tech=0" doc = Hpricot(open(url)).to_s json = JSON.parse(doc) puts json puts json["imdb_id"] 

这给出了以下结果:

 {"rating_count"=>493949, "genres"=>["Drama", "Romance"], "rated"=>"PG-13", "language"=>["English", "French", "German", "Swedish", "Italian", "Russian"], "rating"=>7.6, "country"=>["USA"], "release_date"=>19980403, "title"=>"Titanic", "year"=>1997, "filming_locations"=>"Santa Clarita, California, USA", "imdb_id"=>"tt0120338", "directors"=>["James Cameron"], "writers"=>["James Cameron"], "actors"=>["Leonardo DiCaprio", "Kate Winslet", "Billy Zane", "Kathy Bates", "Frances Fisher", "Gloria Stuart", "Bill Paxton", "Bernard Hill", "David Warner", "Victor Garber", "Jonathan Hyde", "Suzy Amis", "Lewis Abernathy", "Nicholas Cascone", "Anatoly M. Sagalevitch"], "also_known_as"=>["Tai tan ni ke hao"], "poster"=>{"imdb"=>"http://sofzh.miximages.com/ruby/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://sofzh.miximages.com/ruby/338.jpg!cover?_upt=66ac07591382594194"}, "runtime"=>["194 min"], "type"=>"M", "imdb_url"=>"http://www.imdb.com/title/tt0120338/"} tt0120338 

这是预期的。 在第二种情况下,我有同一部电影的titleyear

 url = "http://mymovieapi.com/?title=#{self.title}&type=json&plot=simple&episode=0&limit=1&year=#{self.year}&yg=1&mt=none&lang=en-US&offset=&aka=simple&release=simple&business=0&tech=0" doc = Hpricot(open(url)).to_s json = JSON.parse(doc) puts json puts json["imdb_id"] 

从这里,我得到完全相同的JSON输出:

 {"rating_count"=>493949, "genres"=>["Drama", "Romance"], "rated"=>"PG-13", "language"=>["English", "French", "German", "Swedish", "Italian", "Russian"], "rating"=>7.6, "country"=>["USA"], "release_date"=>19980403, "title"=>"Titanic", "year"=>1997, "filming_locations"=>"Santa Clarita, California, USA", "imdb_id"=>"tt0120338", "directors"=>["James Cameron"], "writers"=>["James Cameron"], "actors"=>["Leonardo DiCaprio", "Kate Winslet", "Billy Zane", "Kathy Bates", "Frances Fisher", "Gloria Stuart", "Bill Paxton", "Bernard Hill", "David Warner", "Victor Garber", "Jonathan Hyde", "Suzy Amis", "Lewis Abernathy", "Nicholas Cascone", "Anatoly M. Sagalevitch"], "also_known_as"=>["Tai tan ni ke hao"], "poster"=>{"imdb"=>"http://sofzh.miximages.com/ruby/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://sofzh.miximages.com/ruby/338.jpg!cover?_upt=ec8bdec31382594417"}, "runtime"=>["194 min"], "type"=>"M", "imdb_url"=>"http://www.imdb.com/title/tt0120338/"} 

但是当我尝试调用puts json["imdb_id"] ,我收到此错误:

 no implicit conversion of String into Integer (TypeError) 

这在使用titleyear获取时总会发生,但由于JSON输出完全相同,因此似乎无法解释。

从exception看,似乎第二个响应中的json是一个只有一个元素的数组,所以puts json的输出是相同的(括号不会得到json["string"]输出),但json["string"]失败,因为[]期望Integer用作索引。

检查p jsonjson.is_a?(Array) ,如果它确实是一个数组,请尝试使用json.first['imdb_id']

这是错误的以及如何解决它:

  • 你没有得到HTML,所以你不需要解析HTML。 请查看以下示例中的doc内容。 请注意,没有HTML解析,也没有任何需要,因为您专门请求JSON响应: type=json
  • 第一个请求返回单个响应,因为您要求特定的imdb_id 。 你只能得到一个回复​​,所以你只得到一个对象/哈希。
  • 第二个请求返回一组响应,因为可能有多个项目具有相同的titleyear ,但似乎不太可能。 因此,在解析JSON之后,您必须从返回的数组中获取特定项。 我first用过,但你的里程可能会有所不同,因为你可以得到多件物品; 如果你得到的不止一个,你必须弄清楚哪个是合适的。

这是一些代码:

 require 'json' require 'open-uri' imdb_id = 'tt0120338' url = "http://mymovieapi.com/?id=#{ imdb_id }&type=json&plot=none&episode=0&lang=en-US&aka=simple&release=simple&business=0&tech=0" doc = open(url).read doc[0..5] # => "{\"rati" json = JSON.parse(doc) # => {"rating_count"=>493949, "genres"=>["Drama", "Romance"], "rated"=>"PG-13", "language"=>["English", "French", "German", "Swedish", "Italian", "Russian"], "rating"=>7.6, "country"=>["USA"], "release_date"=>19980403, "title"=>"Titanic", "year"=>1997, "filming_locations"=>"Santa Clarita, California, USA", "imdb_id"=>"tt0120338", "directors"=>["James Cameron"], "writers"=>["James Cameron"], "actors"=>["Leonardo DiCaprio", "Kate Winslet", "Billy Zane", "Kathy Bates", "Frances Fisher", "Gloria Stuart", "Bill Paxton", "Bernard Hill", "David Warner", "Victor Garber", "Jonathan Hyde", "Suzy Amis", "Lewis Abernathy", "Nicholas Cascone", "Anatoly M. Sagalevitch"], "also_known_as"=>["Tai tan ni ke hao"], "poster"=>{"imdb"=>"http://sofzh.miximages.com/ruby/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://sofzh.miximages.com/ruby/338.jpg!cover?_upt=7dedce781382606097"}, "runtime"=>["194 min"], "type"=>"M", "imdb_url"=>"http://www.imdb.com/title/tt0120338/"} json["imdb_id"] # => "tt0120338" 

这会将单个项目作为JSON响应返回。 你可以通过查看doc变量看到它是JSON,而不是 HTML。 使用JSON解析器解析它返回了一个哈希。

 url = "http://mymovieapi.com/?title=#{ json['title'] }&type=json&plot=simple&episode=0&limit=1&year=#{ json['year'] }&yg=1&mt=none&lang=en-US&offset=&aka=simple&release=simple&business=0&tech=0" doc = open(url).read doc[0..5] # => "[{\"rat" json = JSON.parse(doc).first # => {"rating_count"=>493949, "genres"=>["Drama", "Romance"], "rated"=>"PG-13", "language"=>["English", "French", "German", "Swedish", "Italian", "Russian"], "rating"=>7.6, "country"=>["USA"], "release_date"=>19980403, "title"=>"Titanic", "year"=>1997, "filming_locations"=>"Santa Clarita, California, USA", "imdb_id"=>"tt0120338", "directors"=>["James Cameron"], "writers"=>["James Cameron"], "actors"=>["Leonardo DiCaprio", "Kate Winslet", "Billy Zane", "Kathy Bates", "Frances Fisher", "Gloria Stuart", "Bill Paxton", "Bernard Hill", "David Warner", "Victor Garber", "Jonathan Hyde", "Suzy Amis", "Lewis Abernathy", "Nicholas Cascone", "Anatoly M. Sagalevitch"], "plot_simple"=>"A seventeen-year-old aristocrat, expecting to be married to a rich claimant by her mother, falls in love with a kind but poor artist aboard the luxurious, ill-fated RMS Titanic.", "poster"=>{"imdb"=>"http://sofzh.miximages.com/ruby/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://sofzh.miximages.com/ruby/338.jpg!cover?_upt=7dedce781382606097"}, "runtime"=>["194 min"], "type"=>"M", "imdb_url"=>"http://www.imdb.com/title/tt0120338/", "also_known_as"=>["Tai tan ni ke hao"]} json["imdb_id"] # => "tt0120338" 

这个请求返回了一个哈希数组,这是合理的。 JSON字符串是一个数组,在doc变量中可见。 解析它,然后只抓取第一个元素,可以读取imdb_id的值。

再次注意,没有涉及HTML解析器,也不需要。 你必须看看你要回来的数据,不要只是假设。

从我所知道的,错误必须在代码中的其他位置。

我将您提供的JSON设置为IRB中的变量a :(第二个示例中的JSON)

 1.9.3p194 :043 > a => {"rating_count"=>493949, "genres"=>["Drama", "Romance"], "rated"=>"PG-13", "language"=>["English", "French", "German", "Swedish", "Italian", "Russian"], "rating"=>7.6, "country"=>["USA"], "release_date"=>19980403, "title"=>"Titanic", "year"=>1997, "filming_locations"=>"Santa Clarita, California, USA", "imdb_id"=>"tt0120338", "directors"=>["James Cameron"], "writers"=>["James Cameron"], "actors"=>["Leonardo DiCaprio", "Kate Winslet", "Billy Zane", "Kathy Bates", "Frances Fisher", "Gloria Stuart", "Bill Paxton", "Bernard Hill", "David Warner", "Victor Garber", "Jonathan Hyde", "Suzy Amis", "Lewis Abernathy", "Nicholas Cascone", "Anatoly M. Sagalevitch"], "also_known_as"=>["Tai tan ni ke hao"], "poster"=>{"imdb"=>"http://sofzh.miximages.com/ruby/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://sofzh.miximages.com/ruby/338.jpg!cover?_upt=ec8bdec31382594417"}, "runtime"=>["194 min"], "type"=>"M", "imdb_url"=>"http://www.imdb.com/title/tt0120338/"} 

然后我打电话给:

 1.9.3p194 :046 > puts a["imdb_id"] tt0120338 => nil 

这给了我正确的输出。