【问题标题】:Extract JSON values from remote api with Ruby使用 Ruby 从远程 api 中提取 JSON 值
【发布时间】:2013-05-27 03:16:49
【问题描述】:

我正在尝试从 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"

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

【问题讨论】:

  • 在您尝试访问 data['similarartists']['artist']['name'] 之前,data 是什么样的?你确定你得到了存储在data 中的精确 JSON 吗?
  • 我刚刚做了一个 puts 数据,这里是一个开头的 sn-p {"similarartists"=>{"artist"=>[{"name"=>"Interpol", " mbid"=>"b23e8a63-8f47-4882-b
  • 您是否在 mbid 末尾缺少"?希望我可以对此进行测试,但我没有 Last.FM API 密钥。
  • 没错,输出很长,所以我只发送了第一行,所以你可以看到,这只是我想要的名字。我只是想表明名称不包含任何整数?
  • 您在 cmets 中的结构表明问题是艺术家是艺术家的数组,所以问题是您试图直接采用 ['name'] 但这不是整数索引,这就是红宝石告诉你。应该是data['similarartists']['artist'][0]['name']

标签: ruby json api sinatra


【解决方案1】:

基于 cmets 线程,问题是对 API 调用返回的数据结构的误解。

确切的问题是该结构在艺术家键下有一组艺术家,因此要获得您需要做的名称: data['similarartists']['artist'][0]['name']

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

这会将所有艺术家姓名以逗号分隔。

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

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

【讨论】:

    【解决方案2】:

    问题是您尝试访问索引为"name" 的数组,Ruby 尝试将其转换为整数并失败,导致您看到错误消息。

    如果您测试data["similarartists"]["artist"].classclass,您将看到它返回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 ...
    

    如果你只想要国际刑警组织的 first 条目,你可以使用 index [0]:

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

    【讨论】:

      猜你喜欢
      • 2017-06-19
      • 1970-01-01
      • 2021-05-26
      • 2022-01-02
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 2014-06-12
      • 1970-01-01
      相关资源
      最近更新 更多