您想要实现的是两种编码技术的组合:
-
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.parse和json模块+创建数据对象
首先我们需要导入两个模块:urllib.parse 和 json。然后将原来需要编码的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 dict 或 list 转换为 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.parse和json,并将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 dict 或 list(取决于您是否正在解码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']