json 为什么我得到“没有将字符串隐式转换为整数(TypeError)”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19549098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:57:05  来源:igfitidea点击:

Why do I get "no implicit conversion of String into Integer (TypeError)"?

rubyjson

提问by Andrew

I have some code which I run in very similar circumstances. This is the first circumstance, where I have an imdb_idof a film I want details of:

我有一些在非常相似的情况下运行的代码。这是第一种情况,我有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"]

And this gives the following result:

这给出了以下结果:

{"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

This is as expected. In the second circumstance, I have the titleand yearof the same film:

这正如预期的那样。在第二种情况下,我有同一部电影的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"]

From this, I get the exact same JSON output:

由此,我得到了完全相同的 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/"}

But when I try and call puts json["imdb_id"], I get this error:

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

no implicit conversion of String into Integer (TypeError)

This always happens when fetching using the titleand year, yet it seems unexplained as the JSON output is exactly the same.

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

回答by akhanubis

From the exception, it seems that jsonin the second response is an array with only one element, so the output of puts jsonis the same (brackets don't get output with puts), but json["string"]fails because []expects an Integerto use as index.

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

Check p jsonor that json.is_a?(Array)and if it is indeed an array, try with json.first['imdb_id'].

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

回答by the Tin Man

Here's what's wrong and how to fix it:

这是出了什么问题以及如何解决它:

  • You're NOT getting HTML back, so you do NOTneed to parse HTML. Look at the contents of docin the examples below. Notice, there is no HTML parsing going on, nor is there any need for it because you're specifically requesting a JSON response: type=json.
  • The first request returns a single response because you're asking for a specific imdb_id. You can only get one response back, so you get just a single object/hash.
  • The second request returns an array of responses, because there couldbe multiple items with the same titleand year, though it seems unlikely. As a result, you have to grab a particular item from the returned array after parsing the JSON. I used first, but your mileage might vary since you could get multiple items; You'll have to figure out which is the appropriate one if you do get more than one.
  • 你没有得到HTML回来了,所以你就不要需要解析HTML。看看doc下面例子中的内容。请注意,没有HTML解析回事,也没有任何需要它,因为你特别要求的JSON响应:type=json
  • 第一个请求返回单个响应,因为您要求特定的imdb_id. 你只能得到一个响应,所以你只能得到一个对象/哈希。
  • 第二个请求返回一个响应数组,因为可能有多个项目具有相同的titleand year,尽管这似乎不太可能。因此,您必须在解析 JSON 后从返回的数组中获取特定项。我使用了first,但是您的里程可能会有所不同,因为您可以获得多个物品;如果你得到不止一个,你必须弄清楚哪一个是合适的。

Here's some code:

这是一些代码:

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"

This returned a single item as a JSON response. You can see that by looking at the docvariable and see that it is JSON, NOTHTML. Parsing it using the JSON parser returned a hash.

这将返回单个项目作为 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"

This request returned an array of hashes, which is reasonable. The JSON string is an array, which is visible in the docvariable. Parsing it, then grabbing just the first element makes it possible to read the value of imdb_id.

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

Again, notice that there is no HTML parser involved, nor is one needed. You have to look at the data you're getting back, don't just assume.

再次注意,这里不涉及 HTML 解析器,也不需要。您必须查看返回的数据,不要只是假设。

回答by joncodo

The error must be somewhere else in your code from what I can tell.

据我所知,错误必须在您的代码中的其他地方。

I set the JSON you gave as your output to the variable ain IRB: (JSON from your second example)

我将您作为输出提供的 JSON 设置为aIRB 中的变量:(来自第二个示例的 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/"} 

Then I called:

然后我打电话给:

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

This gave me the right output.

这给了我正确的输出。