删除JSONP以在HTTParty中解析

 hengldkslf 发布于 2023-02-06 18:27

我正在使用谷歌的定义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!方法的数据; 所以我不确定如何在HTTParty尝试解析返回的数据之前添加regexp去除回调参数.

关于这个的任何提示?

2 个回答
  • 使用自定义解析器.在这个例子中,我使用子字符串去除填充,但如果您愿意,可以使用正则表达式:

    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'
    

    2023-02-06 18:28 回答
  • 这很容易做到,除了常规的Ruby以及它附带的JSON和OpenURI类之外什么都没有.考虑一下:

    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结果,因此您无需执行任何特殊操作即可.

    2023-02-06 18:29 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有