JSON到CSV文件Ruby

JSON到CSV文件Ruby,ruby,json,csv,Ruby,Json,Csv,我正试图通过Ruby将以下JSON转换为CSV,但我的代码有问题。我边走边学习,所以任何帮助我都很感激 require 'json' require 'net/http' require 'uri' require 'csv' uri = 'https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&m

我正试图通过Ruby将以下JSON转换为CSV,但我的代码有问题。我边走边学习,所以任何帮助我都很感激

require 'json'
require 'net/http' 
require 'uri' 
require 'csv'

uri = 'https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882_stores_prod%7Copen_status%20=%20?%20OR%20open_status%20=%20?%20OR%20open_status%20=%20?%7CExisting,Coming%20Soon,New%7C' 

response = Net::HTTP.get_response(URI.parse(uri)) 

struct = JSON.parse(response.body.scan(/processPOIs\((.*)\);/).first.first)  


CSV.open("output.csv", "w") do |csv| 
  JSON.parse(struct).read.each do |hash| 
    csv << hash.values
  end
end
require'json'
需要“net/http”
需要“uri”
需要“csv”
乌里https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882存储产品%7Copen_状态%20=%20?%20或%20open_状态%20=%20?%20或%20open_状态%20=%20?%7存在,即将出现,新的%7C'
response=Net::HTTP.get\u响应(URI.parse(URI))
struct=JSON.parse(response.body.scan(/processPOIs\(.*);/).first.first)
CSV.open(“output.CSV”,“w”)do | CSV |
JSON.parse(struct.read.each do|hash|

csv这里有几个问题,最重要的是调用了两次
JSON.parse
。第二次在
struct
上调用它,这是第一次调用
JSON.parse
的结果。您基本上是在做
JSON.parse(JSON.parse(string))
。哎呀

在第二次调用
JSON.parse
的行中还有另一个问题:对它返回的值调用
read
。据我所知,
JSON.parse
通常不会返回响应
read
的任何内容

修复这两个错误后,您的代码如下所示:

struct = JSON.parse(response.body.scan(/processPOIs\((.*)\);/).first.first)

CSV.open("output.csv", "w") do |csv| 
  struct.each do |hash| 
    csv << hash.values
  end
end
String#scan
的目的是查找字符串中与正则表达式匹配的每个子字符串。但是您只关心第一个匹配,因此
scan
是错误的选择

另一种方法是使用
String#match

matches = response.body.match(/processPOIs\((.*)\)/)
json = matches[1]
struct = JSON.parse(json)
然而,这太过分了。由于这是一个JSONP响应,我们知道它将如下所示:

struct = JSON.parse(response.body.scan(/processPOIs\((.*)\);/).first.first)

CSV.open("output.csv", "w") do |csv| 
  struct.each do |hash| 
    csv << hash.values
  end
end
processPOIs(…);
…给出或接受尾随分号或换行符。我们不需要正则表达式来查找括号内的部分,因为我们已经知道它在哪里:它从开头开始13个字符(即索引12),在结尾之前结束两个字符(“索引”-3)。这使得使用
String#slice
,即
String#[]
,工作变得非常简单:

json = response.body[12..-3]
struct = JSON.parse(json)

正如我所说,“给出或获取尾随分号或换行符”,因此您可能需要根据API返回的内容调整结束索引。这样一来,就不会有更难看的
。first.first
,而且速度更快。

这里有几个问题,其中最重要的是调用了
JSON.parse
两次。第二次在
struct
上调用它,这是第一次调用
JSON.parse
的结果。您基本上是在做
JSON.parse(JSON.parse(string))
。哎呀

在第二次调用
JSON.parse
的行中还有另一个问题:对它返回的值调用
read
。据我所知,
JSON.parse
通常不会返回响应
read
的任何内容

修复这两个错误后,您的代码如下所示:

struct = JSON.parse(response.body.scan(/processPOIs\((.*)\);/).first.first)

CSV.open("output.csv", "w") do |csv| 
  struct.each do |hash| 
    csv << hash.values
  end
end
String#scan
的目的是查找字符串中与正则表达式匹配的每个子字符串。但是您只关心第一个匹配,因此
scan
是错误的选择

另一种方法是使用
String#match

matches = response.body.match(/processPOIs\((.*)\)/)
json = matches[1]
struct = JSON.parse(json)
然而,这太过分了。由于这是一个JSONP响应,我们知道它将如下所示:

struct = JSON.parse(response.body.scan(/processPOIs\((.*)\);/).first.first)

CSV.open("output.csv", "w") do |csv| 
  struct.each do |hash| 
    csv << hash.values
  end
end
processPOIs(…);
…给出或接受尾随分号或换行符。我们不需要正则表达式来查找括号内的部分,因为我们已经知道它在哪里:它从开头开始13个字符(即索引12),在结尾之前结束两个字符(“索引”-3)。这使得使用
String#slice
,即
String#[]
,工作变得非常简单:

json = response.body[12..-3]
struct = JSON.parse(json)

正如我所说,“给出或获取尾随分号或换行符”,因此您可能需要根据API返回的内容调整结束索引。这样一来,就不会再难看了。
。首先。首先
,而且速度也更快。

谢谢大家的帮助。我能够把所有的东西都放到CSV中,然后用VBA按照我想要的方式组织起来

require 'json'
require 'net/http' 
require 'uri' 
require 'csv'

uri = 'https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882_stores_prod%7Copen_status%20=%20?%20OR%20open_status%20=%20?%20OR%20open_status%20=%20?%7CExisting,Coming%20Soon,New%7C' 

response = Net::HTTP.get_response(URI.parse(uri)) 

matches = response.body.match(/processPOIs\((.*)\)/)
json = response.body[12..-3]
struct = JSON.parse(json)

CSV.open("output.csv", "w") do |csv| 

    csv << struct['searchResults'].map { |result| result['fields']}
  end
require'json'
需要“net/http”
需要“uri”
需要“csv”
乌里https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882存储产品%7Copen_状态%20=%20?%20或%20open_状态%20=%20?%20或%20open_状态%20=%20?%7存在,即将出现,新的%7C'
response=Net::HTTP.get\u响应(URI.parse(URI))
matches=response.body.match(/processPOIs\(.*)/)
json=response.body[12..-3]
struct=JSON.parse(JSON)
CSV.open(“output.CSV”,“w”)do | CSV |

csv谢谢大家的帮助。我能够把所有的东西都放到CSV中,然后用VBA按照我想要的方式组织起来

require 'json'
require 'net/http' 
require 'uri' 
require 'csv'

uri = 'https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882_stores_prod%7Copen_status%20=%20?%20OR%20open_status%20=%20?%20OR%20open_status%20=%20?%7CExisting,Coming%20Soon,New%7C' 

response = Net::HTTP.get_response(URI.parse(uri)) 

matches = response.body.match(/processPOIs\((.*)\)/)
json = response.body[12..-3]
struct = JSON.parse(json)

CSV.open("output.csv", "w") do |csv| 

    csv << struct['searchResults'].map { |result| result['fields']}
  end
require'json'
需要“net/http”
需要“uri”
需要“csv”
乌里https://www.mapquestapi.com/search/v2/radius?key=Imjtd%7Clu6t200zn0,bw=o5-layg1&radius=3000&callback=processPOIs&maxMatches=4000&origin=40.7686973%2C-73.9918181&hostedData=mqap.33882存储产品%7Copen_状态%20=%20?%20或%20open_状态%20=%20?%20或%20open_状态%20=%20?%7存在,即将出现,新的%7C'
response=Net::HTTP.get\u响应(URI.parse(URI))
matches=response.body.match(/processPOIs\(.*)/)
json=response.body[12..-3]
struct=JSON.parse(JSON)
CSV.open(“output.CSV”,“w”)do | CSV |

csv您遇到了什么具体问题?只是没有写入csv。我一直收到一个指向JSON.parse(struct)行的错误。您收到了什么错误?您确定
response.body
是您所期望的吗?您是否检查了
response.body.scan(/processPOIs\(.*);/)
实际上是JSON?获取错误:在“block in”中。正如我提到的,我对这一切都是新手。我认为response.body.scan将JSON转换为te