【问题标题】:Why do I get "no implicit conversion of String into Integer (TypeError)"?为什么我得到“没有将字符串隐式转换为整数(TypeError)”?
【发布时间】:2013-11-02 04:00:08
【问题描述】:

我有一些代码在非常相似的情况下运行。这是第一种情况,我有一个电影的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://ia.media-imdb.com/images/M/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://imdb-poster.b0.upaiyun.com/000/120/338.jpg!cover?_upt=66ac07591382594194"},
"runtime"=>["194 min"],
"type"=>"M",
"imdb_url"=>"http://www.imdb.com/title/tt0120338/"}

tt0120338

这符合预期。第二种情况,我有同一部电影的title和year:

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://ia.media-imdb.com/images/M/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg",
"cover"=>"http://imdb-poster.b0.upaiyun.com/000/120/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)

使用title 和year 获取时总是会发生这种情况,但似乎无法解释,因为 JSON 输出完全相同。

【问题讨论】:

  • 是"put json["imdb_id"]"还是"puts"?并且你能发布为第二种类型返回的 json 吗?
  • @AmithKoujalgi 是的,我在这里输入了那个小部分并犯了一个错误。我已经复制了第二个 json 输出,但是完全一样。
  • 您为什么使用 Hpricot?为什么要使用 Hpricot 来“解析”收到的 JSON 输出?首先,它不是必需的,它也已被 Nokogiri 取代,因此,IF 您需要解析 HTML,而您不需要,您最好使用更新的 HTML 解析器。
  • @theTinMan 我对 JSON 还很陌生(这是我第一个真正使用它的应用程序),所以感谢您的提醒。我不确定如何从网页中获取 JSON,并且我在其他地方使用 Hpricot,所以用它来做到这一点。我应该怎么做?使用 Nokogiri 还是其他方式?
  • 不要使用 Nokogiri 或 Hpricot。您正在请求 JSON 响应,这就是您得到的。

标签: ruby json


【解决方案1】:

从异常看来,第二个响应中的json似乎是一个只有一个元素的数组,所以puts json的输出是一样的(括号里没有puts的输出),但是@ 987654324@ 失败,因为 [] 期望将 Integer 用作索引。

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

【讨论】:

  • 我不认为这是一个数组。
  • puts [1] 将输出与 puts 1(1) 相同的输出,因为它将输出由新行分隔的每个元素。从问题中给出的输出无法知道 json 是显示的散列还是实际上包含显示的散列的数组。安德鲁应该检查json.class 或json.inspect
  • 第二个 JSON 响应返回一个数组。这是第一个:doc[0..5] # => "{\"rati",第二个:doc[0..5] # => "[{\"rat"。
【解决方案2】:

这里有什么问题以及如何解决它:

  • 您没有返回 HTML,因此您确实不需要解析 HTML。在下面的示例中查看doc 的内容。请注意,没有进行 HTML 解析,也不需要它,因为您专门请求 JSON 响应:type=json。
  • 第一个请求返回一个响应,因为您请求的是特定的imdb_id。您只能得到一个响应,因此您只会得到一个对象/哈希。
  • 第二个请求返回一个响应数组,因为可能有多个具有相同title 和year 的项目,尽管这似乎不太可能。因此,您必须在解析 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://ia.media-imdb.com/images/M/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://imdb-poster.b0.upaiyun.com/000/120/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 R.M.S. Titanic.", "poster"=>{"imdb"=>"http://ia.media-imdb.com/images/M/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://imdb-poster.b0.upaiyun.com/000/120/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 解析器,也不需要。你必须看看你得到的数据,不要只是假设。

【讨论】:

    【解决方案3】:

    据我所知,错误一定是在您的代码中的其他地方。

    我将您提供的 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://ia.media-imdb.com/images/M/MV5BMjExNzM0NDM0N15BMl5BanBnXkFtZTcwMzkxOTUwNw@@._V1_SY317_CR0,0,214,317_.jpg", "cover"=>"http://imdb-poster.b0.upaiyun.com/000/120/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 
    

    这给了我正确的输出。

    【讨论】:

      猜你喜欢
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多