【问题标题】:How do I encode this dictionary of URL parameters into a valid string?如何将此 URL 参数字典编码为有效字符串?
【发布时间】:2021-03-17 16:40:06
【问题描述】:

我有一个 Python 字典 params,看起来像这样:

{
    "request": {
        "metadataOnly":False,
        "latitude": 80.12345,
        "treatmentFlags":[
            "simple_search_1_1",
            "simple_search_desktop_v3_full_bleed",
            "flexible_dates_options_extend_one_three_seven_days"
        ]
    }
}

我想把params转换成这个字符串:

%7B%22request%22%3A%7B%22metadataOnly%22%3A%22false%22%2C%22latitude%22%3A%2280.12345%22%2C%22treatmentFlags%22%3A%5B%22simple_search_1_1%22%2C%22simple_search_desktop_v3_full_bleed%22%2C%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D

因为该字符串在我查询的 URL 中有效。该字符串在使用Advanced REST Client 解码时如下所示:

{"request":{"metadataOnly":"false","latitude":"80.12345","treatmentFlags":["simple_search_1_1","simple_search_desktop_v3_full_bleed","flexible_dates_options_extend_one_three_seven_days"]}}

如何将params 或任何此类 Python 字典转换为我描述的有效字符串?

【问题讨论】:

    标签: python python-3.x rest url get


    【解决方案1】:

    您想要实现的是两种编码技术的组合:

    • JSON 编码(将字典转换为字符串)
    • URL 编码(对字符串进行编码以使其在 URL 查询字符串中使用安全)

    在这个答案中,我包含了两个 Python 示例,逐步分解,以及一个 Tl;Dr 最小编码+解码示例,供那些不需要/想要完整解释的人使用这是如何工作的。

    第一个示例显示如何根据问题中所需的最终结果字符串将 dict/list 转换为 URL 编码的 JSON 字符串,第二个示例显示如何反转该过程 - 将 URL 编码的 JSON 字符串转换回原始 JSON 字符串,然后将该 转换回其原始 dict 对象。

    TL;DR;完整的代码,最少的解释

    向下滚动查看带有完整分步说明的细分。此代码块是 TL;DR;示例 - 将编码覆盖到 URL 字符串中,然后返回到 dict,使用最少的 cmets 和节省空间的格式。

    import urllib.parse
    import json
    
    data = {
        "request": { "metadataOnly":False, "latitude": 80.12345,
            "treatmentFlags":["simple_search_1_1", "simple_search_desktop_v3_full_bleed", "flexible_dates_options_extend_one_three_seven_days"]}
    }
    
    j = json.dumps(data)             # Convert 'data' into a JSON string
    
    u = urllib.parse.quote_plus(j)   # URL encode the JSON string
    # 'u' now contains the desired result, starting with '%7B%22request%22%3A%7B%22metadataOnly%22%3A%22f' ...
    
    # Reversing the process (url string back to dict)
    
    # Decode the URL encoded string 'u' back into a normal JSON string
    dec = urllib.parse.unquote_plus(u)
    # Import the JSON string back into a Python dict (jd is effectively the same as 'data')
    jd = json.loads(dec)
    print(jd['request']['treatmentFlags'])
    # Output: ['simple_search_1_1', 'simple_search_desktop_v3_full_bleed', 'flexible_dates_options_extend_one_three_seven_days']
    

    Python 示例(将 dict / 列表编码为 URL 编码的 JSON)

    导入urllib.parsejson模块+创建数据对象

    首先我们需要导入两个模块:urllib.parsejson。然后将原来需要编码的dict声明为变量data

    import urllib.parse
    import json
    
    data = {
        "request": {
            "metadataOnly":False,
            "latitude": 80.12345,
            "treatmentFlags":[
                "simple_search_1_1",
                "simple_search_desktop_v3_full_bleed",
                "flexible_dates_options_extend_one_three_seven_days"
            ]
        }
    }
    

    使用 JSON 将变量 'data' 编码为变量 'j'

    使用 json 模块中的 dumps,您可以将 Python dictlist 转换为 JSON 编码字符串

    j = json.dumps(data)
    
    # You can see that 'j' is now a string
    print(type(j))
    # Output:
    #  <class 'str'>
    
    # If we print 'j', you can see the contents have been encoded as JSON
    print(j)
    # Output:
    #
    #   {"request": {"metadataOnly": false, "latitude": 80.12345, 
    #   "treatmentFlags": ["simple_search_1_1", 
    #   "simple_search_desktop_v3_full_bleed", 
    #   "flexible_dates_options_extend_one_three_seven_days"]}}
    

    将“j”编码为 URL 编码变量“u”

    现在我们将 JSON 字符串转换为变量 'u' 中的编码 URL 字符 以便在 URL 查询字符串中使用它是安全的

    ####
    # Now we convert the JSON string into encoded URL characters in variable 'u'
    # so that it's safe for use in a URL query string
    ####
    u = urllib.parse.quote_plus(j)
    
    # If we print the variable 'u', you can see it's now encoded in URL safe format
    print(u)
    # Output:
    #
    #   %7B%22request%22%3A+%7B%22metadataOnly%22%3A+false%2C+%22latitude
    #   %22%3A+80.12345%2C+%22treatmentFlags%22%3A+%5B%22simple_search_1_1
    #   %22%2C+%22simple_search_desktop_v3_full_bleed
    #   %22%2C+%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D
    

    逆向处理(将 URL 编码的 JSON 解码回字典/列表)

    如果您稍后需要将 URL 编码字符串解码回 JSON 和/或字典,我们可以像这样反转该过程:

    再次导入模块 + 声明 URL 编码字符串 'u'

    首先我们像之前一样导入urllib.parsejson,并将URL编码字符串声明为u

    import urllib.parse
    import json
    
    u = "%7B%22request%22%3A+%7B%22metadataOnly%22%3A+false%2C+%22latitude" + \
        "%22%3A+80.12345%2C+%22treatmentFlags%22%3A+%5B%22simple_search_1_1" + \
        "%22%2C+%22simple_search_desktop_v3_full_bleed" + \
        "%22%2C+%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D"
    

    将 URL 编码字符串解码回原始 JSON 字符串

    使用来自urllib.parse 模块的unquote_plus,您可以解码已被URL 编码的字符串(即%22hello%20world%22

    dec = urllib.parse.unquote_plus(u)
    
    print(dec)
    # Output:
    #
    # {"request": {"metadataOnly": false, "latitude": 80.12345, "treatmentFlags": ["simple_search_1_1", "simple_search_desktop_v3_full_bleed", "flexible_dates_options_extend_one_three_seven_days"]}}
    

    将 JSON 字符串加载到标准 Python 字典/列表中

    使用 json 模块中的 loads,您可以将 JSON 字符串 (str) 或 bytes 对象导入标准 Python dictlist(取决于您是否正在解码JSON 列表或字典)

    jd = json.loads(dec)
    
    print(jd['request']['metadataOnly'])
    # Output: False
    
    print(jd['request']['treatmentFlags'])
    # Output: 
    #
    #   ['simple_search_1_1', 'simple_search_desktop_v3_full_bleed', 'flexible_dates_options_extend_one_three_seven_days']
    

    【讨论】:

      【解决方案2】:

      我猜你可以使用 Python 库,它是 urllib
      这样,它将获取您在字典中的数据。并以 URL
      的形式返回 例如:-\

      import urllib.parse
      data={
          "request": {
              "metadataOnly":False,
              "latitude": 80.12345,
              "treatmentFlags":[
                  "simple_search_1_1",
                  "simple_search_desktop_v3_full_bleed",
                  "flexible_dates_options_extend_one_three_seven_days"
              ]
          }
      }
      data_in_form_of_URL = urllib.parse.urlencode(data)
      print("Your URL is:-",str(data_in_form_of_URL))
      

      你会得到如下输出:-

      Your URL is:- request=%7B%27metadataOnly%27%3A+False%2C+%27latitude%27%3A+80.12345%2C+%27treatmentFlags%27%3A+%5B%27simple_search_1_1%27%2C+%27simple_search_desktop_v3_full_bleed%27%2C+%27flexible_dates_options_extend_one_three_seven_days%27%5D%7D
      

      【讨论】:

      • 这很接近,但与我想要的字符串不匹配。
      • 噢,我真的很抱歉先生。我无法帮助你..
      猜你喜欢
      • 1970-01-01
      • 2014-06-24
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 2017-04-16
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多