使用Ruby从远程api中提取JSON值

时间:2013-05-27 03:16:49

标签: ruby json api sinatra

我正在尝试从last.fm获取一些数据并在一个简单的sinatra应用程序中使用它。我已经弄清楚如何打开文档但是在ruby中提取数据的问题是我想要获取名称的第一个API数据列表:

  

{“similarartists”:{“artist”:[{“name”:“Sonny& Cher”}}}

这只是返回的摘录,我在我的rb文件中使用它:

require 'json'
require 'open-uri'

data = JSON.parse(open("http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist=editors&api_key=xxx&format=json").read)

puts data["similarartists"]["artist"]["name"]

它似乎没有工作我得到无法在Ruby 1.9.3上将String转换为Integer(TypeError),但JSON中的名称不是整数?如果我只是提出以下内容:

puts data["similarartists"]["artist"]

它返回整个内容,但我想抓住内部并得到名称。

"name"=>"Interpol"

我不明白为什么当名字是一个字符串时它会抱怨整数?希望有人可以帮助我!

2 个答案:

答案 0 :(得分:2)

基于评论主题,问题是对API调用返回的数据结构的误解。

确切的问题是结构在艺术家关键字下有一系列艺术家,所以要得到你需要做的名字:  data['similarartists']['artist'][0]['name']

请注意,如果您确定只有一位艺术家,那么您应该这样做。返回数据的性质表明情况并非总是如此,因此根据您的使用情况,您最好不要使用所有名称: data['similarartists']['artist'].map {|a| a['name']}.join(',')

将所有艺术家的名字加在一起以逗号分隔。

将来,您可以通过查看返回数据的完整结构并确保查看正确的结构来跟踪此问题。 API上的文档也可能在这里提供一些帮助。

您还可以检查某人是否已创建用于访问API的gem。宝石通常会提升一些原始输出,并为您提供一个很好的对象。我建议在GitHub上搜索last.fm gem。

答案 1 :(得分:1)

问题是您正在尝试访问索引为"name"的Array,Ruby会尝试将其转换为Integer并失败,从而导致您看到错误消息。

如果您测试class的{​​{1}},您会看到它返回data["similarartists"]["artist"].class。所以基本上发生的事情是调用的Array被创建为JSON.parse()哈希数组的值。要访问所有艺术家名称,您只需遍历此数组:

data["similarartists"]["artist"]

如果你只想要国际刑警组织的第一个条目,你可以使用索引require 'json' require 'open-uri' data = JSON.parse(open("http://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist=editors&api_key=29da5a0e01ca2d1524cac596d5462d67&format=jso\ n").read) # iterate through the Array of returned artists and print their names data["similarartists"]["artist"].each do |artist| puts artist["name"] end # output # Interpol # White Lies # The Cinematics # Smith & Burrows # The National # Julian Plenti # She Wants Revenge # etc ...

[0]