簡體   English   中英

刪除JSONP以在HTTParty中解析

[英]Remove JSONP for parsing in HTTParty

我正在使用谷歌的定義URL,它返回一個包含JSONP數據的響應流(見下文)。

GET http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome

響應如下:

a({"query": "epitome", ...}, 200, null)

在解析JSON之前,我必須去掉回調參數; 這意味着在第一個{和最后一個之后的一切}之前刪除所有內容。

我有正則表達式去除回調參數,但在使用HTTParty請求時遇到問題。

正則表達式以剝離填充

^\w+\(|[^}]+$

我嘗試過使用以下內容,但收到錯誤。

base_url = "http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q="
word = "epitome"

request = HTTParty.get("#{base_url}#{word}").gsub(/^\w+\(|[^}]+$/)

HTTParty自動嘗試解析忽略gsub!的數據gsub! 方法; 所以我不確定如何在HTTParty嘗試解析返回的數據之前添加regexp去除回調參數。

關於這個的任何提示?

使用自定義解析器。 在這個例子中,我使用子字符串去除填充,但如果您願意,可以使用正則表達式:

require 'httparty'

class JsonpParser < HTTParty::Parser
  SupportedFormats = {"text/javascript" => :jsonp}

  def jsonp
    JSON.load(body[2..-11], nil)
  end

end

class Dictionary
  include HTTParty

  parser JsonpParser

  def self.define(word)
    get "http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=#{word}"
  end

end

Dictionary.define 'epitome'

這很容易做到,除了常規的Ruby以及它附帶的JSONOpenURI類之外什么都沒有。 考慮一下:

require 'open-uri'
require 'json'

URL = 'http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome'
jsonp = open(URL).read

此時, jsonp包含來自Google API的響應。 你想要的部分用大括號{...}包裹。

正則表達式是貪婪的,並且會吞噬它們所能做的一切。 通常這是一個問題,但在這種情況下它是好的。 一個簡單的/{.+}/ { }模式將找到從第一個{到最后一個} ,即JSON有效負載,此時,您已准備好解析:

payload = jsonp[/{.+}/]
# => "{\"query\":\"epitome\",\"sourceLanguage\":\"en\",\"targetLanguage\":\"en\",\"primaries\":[{\"type\":\"headword\",\"terms\":[{\"type\":\"text\",\"text\":\"e·pit·o·me\",\"language\":\"en\",\"labels\":[{\"text\":\"Noun\",\"title\":\"Part-of-speech\"}]},{\"type\":\"phonetic\",\"text\":\"/iˈpitəmē/\",\"language\":\"und\"},{\"type\":\"sound\",\"text\":\"http://www.gstatic.com/dictionary/static/sounds/de/0/epitome.mp3\",\"language\":\"und\"}],\"entries\":[{\"type\":\"related\",\"terms\":[{\"type\":\"text\",\"text\":\"epitomes\",\"language\":\"und\",\"labels\":[{\"text\":\"plural\"}]}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A person or thing that is a perfect example of a particular quality or type\",\"language\":\"en\"}],\"entries\":[{\"type\":\"example\",\"terms\":[{\"type\":\"text\",\"text\":\"she looked the \\x3cem\\x3eepitome\\x3c/em\\x3e of elegance and good taste\",\"language\":\"en\"}]}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A summary of a written work; an abstract\",\"language\":\"en\"}]},{\"type\":\"meaning\",\"terms\":[{\"type\":\"text\",\"text\":\"A thing representing something else in miniature\",\"language\":\"en\"}]}]}]}"

解析:

data = JSON.parse(payload)
# => {"query"=>"epitome",
#     "sourceLanguage"=>"en",
#     "targetLanguage"=>"en",
#     "primaries"=>
#      [{"type"=>"headword",
#        "terms"=>
#         [{"type"=>"text",
#           "text"=>"e·pit·o·me",
#           "language"=>"en",
#           "labels"=>[{"text"=>"Noun", "title"=>"Part-of-speech"}]},
#          {"type"=>"phonetic", "text"=>"/iˈpitəmē/", "language"=>"und"},
#          {"type"=>"sound",
#           "text"=>
#            "http://www.gstatic.com/dictionary/static/sounds/de/0/epitome.mp3",
#           "language"=>"und"}],
#        "entries"=>
#         [{"type"=>"related",
#           "terms"=>
#            [{"type"=>"text",
#              "text"=>"epitomes",
#              "language"=>"und",
#              "labels"=>[{"text"=>"plural"}]}]},
#          {"type"=>"meaning",
#           "terms"=>
#            [{"type"=>"text",
#              "text"=>
#               "A person or thing that is a perfect example of a particular quality or type",
#              "language"=>"en"}],
#           "entries"=>
#            [{"type"=>"example",
#              "terms"=>
#               [{"type"=>"text",
#                 "text"=>
#                  "she looked the x3cemx3eepitomex3c/emx3e of elegance and good taste",
#                 "language"=>"en"}]}]},
#          {"type"=>"meaning",
#           "terms"=>
#            [{"type"=>"text",
#              "text"=>"A summary of a written work; an abstract",
#              "language"=>"en"}]},
#          {"type"=>"meaning",
#           "terms"=>
#            [{"type"=>"text",
#              "text"=>"A thing representing something else in miniature",
#              "language"=>"en"}]}]}]}

現在你已經有了一個很好的ol'Ruby hash,你可以正常訪問:

data['query'] # => "epitome"

總結一下:

require 'open-uri'
require 'json'

URL = 'http://www.google.com/dictionary/json?callback=a&sl=en&tl=en&q=epitome'

data = JSON.parse(open(URL).read[/{.+}/])

data['query'] # => "epitome"
data['primaries'].size # => 1

而且,它也適用於常規JSON結果,因此您無需執行任何特殊操作即可。

將httparty更新為最新版本,因為此處已修復。 在JSON被禁用時解析javascript響應,這意味着HTTParty.get將返回一個字符串,您可以自己進行替換和解析。

它僅在響應具有正確的內容類型(您的示例中的Google服務)時才有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM