如何使用 Nokogiri return 一个 JSON 对象
How to return a JSON object with Nokogiri
我需要得到一个 JSON 对象:
curl -X GET "https://graph.facebook.com/v2.6/<USER_ID>?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=PAGE_ACCESS_TOKEN"
在 Rails 中,我正在使用 Nokogiri:
# Get the data
data = Nokogiri::HTML(open(<URL>))
我得到的结果是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p><JSON-OBJECT></p></body></html>
我只需要 return JSON 对象,所以我认为这可行:
Hash.from_xml(data.to_xml)['html']['body']['p'].remove('\')
没有。我如何才能像在终端中使用 cURL 一样只获取 JSON 对象?
我不确定您为什么要使用 Nokogiri 来解析 JSON 对象。 Nokogiri 用于解析 XML/HTML。 Facebook API 的默认响应类型已经是 JSON.
最好使用 httparty, faraday,或者使用纯 ol OpenURI 和 JSON.parse
。
在 cURL 上:
curl -i -H "Content-type: application/json" -H "Accept: application/json" -X GET \"https://graph.facebook.com/v2.8/me?fields=id%2Cname&access_token=<ACCESS_TOKEN>
通常,JSON 响应未编码或包含在 HTML 页面中,它作为包含整个正文的文本字符串返回:
require 'open-uri'
open('http://httpbin.org/headers').read
# => "{\n" +
# " \"headers\": {\n" +
# " \"Accept\": \"*/*\", \n" +
# " \"Accept-Encoding\": \"gzip;q=1.0,deflate;q=0.6,identity;q=0.3\", \n" +
# " \"Host\": \"httpbin.org\", \n" +
# " \"User-Agent\": \"Ruby\"\n" +
# " }\n" +
# "}\n"
将其解析回 Ruby 对象很容易:
require 'json'
require 'open-uri'
JSON[open('http://httpbin.org/headers').read]
# => {"headers"=>
# {"Accept"=>"*/*",
# "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
# "Host"=>"httpbin.org",
# "User-Agent"=>"Ruby"}}
JSON[...]
是一种简单、通用的解析 JSON 字符串或序列化 Ruby 对象的方法。它足够聪明,知道该怎么做:
require 'json'
foo = {'a' => 1}
foo.class # => Hash
bar = JSON[foo] # => "{\"a\":1}"
bar.class # => String
baz = JSON[bar] # => {"a"=>1}
baz.class # => Hash
如果您想更明确一点,可以使用 to_json
和 parse
方法:
require 'json'
foo = {'a' => 1}
bar = foo.to_json # => "{\"a\":1}"
baz = JSON.parse(bar) # => {"a"=>1}
请注意,任何时候都不需要 Nokogiri。
如果,由于某些奇怪的原因,JSON 被注入到页面中,或者您可能想获取一些 JavaScript 数据,这是更有可能的是,你可以使用 Nokogiri:
require 'json'
require 'nokogiri'
html = <<EOT
<html>
<head>
<script>
var foo = '{"a":1}';
</script>
</head>
</html>
EOT
doc = Nokogiri::HTML(html)
script_contents = doc.at('script').text # => "\n var foo = '{\"a\":1}';\n "
foo = JSON[script_contents[/({.+})/, 1]] # => {"a"=>1}
foo.class # => Hash
我需要得到一个 JSON 对象:
curl -X GET "https://graph.facebook.com/v2.6/<USER_ID>?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=PAGE_ACCESS_TOKEN"
在 Rails 中,我正在使用 Nokogiri:
# Get the data
data = Nokogiri::HTML(open(<URL>))
我得到的结果是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p><JSON-OBJECT></p></body></html>
我只需要 return JSON 对象,所以我认为这可行:
Hash.from_xml(data.to_xml)['html']['body']['p'].remove('\')
没有。我如何才能像在终端中使用 cURL 一样只获取 JSON 对象?
我不确定您为什么要使用 Nokogiri 来解析 JSON 对象。 Nokogiri 用于解析 XML/HTML。 Facebook API 的默认响应类型已经是 JSON.
最好使用 httparty, faraday,或者使用纯 ol OpenURI 和 JSON.parse
。
在 cURL 上:
curl -i -H "Content-type: application/json" -H "Accept: application/json" -X GET \"https://graph.facebook.com/v2.8/me?fields=id%2Cname&access_token=<ACCESS_TOKEN>
通常,JSON 响应未编码或包含在 HTML 页面中,它作为包含整个正文的文本字符串返回:
require 'open-uri'
open('http://httpbin.org/headers').read
# => "{\n" +
# " \"headers\": {\n" +
# " \"Accept\": \"*/*\", \n" +
# " \"Accept-Encoding\": \"gzip;q=1.0,deflate;q=0.6,identity;q=0.3\", \n" +
# " \"Host\": \"httpbin.org\", \n" +
# " \"User-Agent\": \"Ruby\"\n" +
# " }\n" +
# "}\n"
将其解析回 Ruby 对象很容易:
require 'json'
require 'open-uri'
JSON[open('http://httpbin.org/headers').read]
# => {"headers"=>
# {"Accept"=>"*/*",
# "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
# "Host"=>"httpbin.org",
# "User-Agent"=>"Ruby"}}
JSON[...]
是一种简单、通用的解析 JSON 字符串或序列化 Ruby 对象的方法。它足够聪明,知道该怎么做:
require 'json'
foo = {'a' => 1}
foo.class # => Hash
bar = JSON[foo] # => "{\"a\":1}"
bar.class # => String
baz = JSON[bar] # => {"a"=>1}
baz.class # => Hash
如果您想更明确一点,可以使用 to_json
和 parse
方法:
require 'json'
foo = {'a' => 1}
bar = foo.to_json # => "{\"a\":1}"
baz = JSON.parse(bar) # => {"a"=>1}
请注意,任何时候都不需要 Nokogiri。
如果,由于某些奇怪的原因,JSON 被注入到页面中,或者您可能想获取一些 JavaScript 数据,这是更有可能的是,你可以使用 Nokogiri:
require 'json'
require 'nokogiri'
html = <<EOT
<html>
<head>
<script>
var foo = '{"a":1}';
</script>
</head>
</html>
EOT
doc = Nokogiri::HTML(html)
script_contents = doc.at('script').text # => "\n var foo = '{\"a\":1}';\n "
foo = JSON[script_contents[/({.+})/, 1]] # => {"a"=>1}
foo.class # => Hash