我有一个要加载的JSON字符串:
{"a": 1, "b": {"c": 123} }
如果我使用json.loads
,则会将{"c": 123}
加载为dict
。但是,我不希望这种情况发生。
我希望能够直接访问字符串,而无需将内部对象解释为dict,如下所示:
json_dict['b'] == '{"c": 123}'
而不是
json_dict['b'] == {"c": 123}
因为格式(如空格)和顺序(在dict
中将是随机的)可能会改变,并且需要确切的字符串来进行RSA验证。
实际代码如下:
r = requests.get('https://openapi.alipaydev.com/gateway.do', params)
print(r.text)
response = json.loads(r.text)
print(response)
alipay_response = response['alipay_trade_precreate_response']
print(alipay_response['code'])
输出结果为:
{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"123","qr_code":"https:\/\/qr.alipay.com\/bax08377e7kxveupoqnt001c"},"sign":"EqocoROqXbpkGdkFZakEkoOymGS7+UcvNi1YmcQffF4wtyQcj/RTO1sLHY8tWZFx0rxQAPjkX+7Hrszn4pNWkuBbM/c88oEbxYc+pCvnF49SHZmfkBqY6eJlLIHgPHXus5KFtvlMmkzANNHmD7c72FLDAbvMHKVyEcRPkU9ANIk="}
{'sign': 'EqocoROqXbpkGdkFZakEkoOymGS7+UcvNi1YmcQffF4wtyQcj/RTO1sLHY8tWZFx0rxQAPjkX+7Hrszn4pNWkuBbM/c88oEbxYc+pCvnF49SHZmfkBqY6eJlLIHgPHXus5KFtvlMmkzANNHmD7c72FLDAbvMHKVyEcRPkU9ANIk=', 'alipay_trade_precreate_response': {'out_trade_no': '123', 'qr_code': 'https://qr.alipay.com/bax08377e7kxveupoqnt001c', 'msg': 'Success', 'code': '10000'}}
10000
我们可以看到response['alipay_trade_precreate_response']
是dict
,订单与字符串不同。我需要字符串,以便我可以验证RSA签名。
答案 0 :(得分:0)
直接回答您的问题:不,json.loads
不支持此问题。
我在下面列出了两种实现目标的方法。第一个非常强大,依赖于ijson
的词法分析器。第二种方法不太稳健,依赖于正则表达式。
json_string = '{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"123","qr_code":"https:\/\/qr.alipay.com\/bax08377e7kxveupoqnt001c"},"sign":"EqocoROqXbpkGdkFZakEkoOymGS7+UcvNi1YmcQffF4wtyQcj/RTO1sLHY8tWZFx0rxQAPjkX+7Hrszn4pNWkuBbM/c88oEbxYc+pCvnF49SHZmfkBqY6eJlLIHgPHXus5KFtvlMmkzANNHmD7c72FLDAbvMHKVyEcRPkU9ANIk="}'
# METHOD 1:
# ---------
import ijson
import io
def get_raw_dict_string(json_string, key='alipay_trade_precreate_response'):
tokens = [[pos, symbol] for pos, symbol in ijson.backends.python.Lexer(io.StringIO(json_string))]
if tokens[0][1] != '{':
raise Exception("not a dictionary")
start = None
end = None
i = 0
level = 0
while i < len(tokens):
pos, symbol = tokens[i]
if symbol == '{':
level += 1
elif symbol == '}':
level -= 1
if level == 1:
end = pos
break
elif level == 1 and symbol[0] == '"':
if ijson.backends.python.unescape(symbol[1:-1]) == key:
if tokens[i+1][1] == ':' and tokens[i+2][1] == '{':
start = tokens[i+2][0]
i += 2
level += 1
i += 1
return json_string[start:end+1]
print(get_raw_dict_string(json_string))
# Output:
# {"code":"10000","msg":"Success","out_trade_no":"123","qr_code":"https:\/\/qr.alipay.com\/bax08377e7kxveupoqnt001c"}
# METHOD 2:
# ---------
import re
print(re.search(r'"alipay_trade_precreate_response"\s*:\s*({[^}]*})', json_string).group(1))
# Output:
# {"code":"10000","msg":"Success","out_trade_no":"123","qr_code":"https:\/\/qr.alipay.com\/bax08377e7kxveupoqnt001c"}