2017-02-27 63 views
0

返回一個JSON對象,我需要得到一個JSON對象:如何與引入nokogiri

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> 

我需要返回只是JSON對象,所以我認爲這會工作:

Hash.from_xml(data.to_xml)['html']['body']['p'].remove('\') 

沒有。如何獲取JSON對象,就好像我在終端中使用了cURL一樣?

回答

1

我不確定爲什麼要使用Nokogiri來解析JSON對象。 Nokogiri用於解析XML/HTML。 Facebook API的默認響應類型已經是JSON。

更好地使用httparty, faraday或普通的OpenURI和JSON.parse

這裏,它是捲曲:

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> 
+0

老實說,我認爲nokogirl是在這種情況下使用的。我無法讓faraday工作,但是httparty工作。謝謝! – Sylar

+0

Ruby有許多有用的HTTP客戶端。有關列表,請參閱https://www.ruby-toolbox.com/categories/http_clients。 –

+0

@theTinMan我嗨嗨剛剛試過你的答案,那也工作。謝謝,但在這個階段我的知識似乎有所進步 – Sylar

2

通常,在HTML頁面中的JSON響應沒有編碼或包含,它返回一個字符串,它包括整個身體:

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_jsonparse方法:

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