【发布时间】:2018-05-26 07:36:41
【问题描述】:
我正在尝试从 api 获取产品数据。
默认情况下,此 api 返回 20 个产品,如果我们使用 api 的参数 Limit=500,则在单个请求中,该 api 最多可以返回 500 个产品。
因此,为了获取所有产品,我们需要使用一个带有 Limit-Offset(要跳过的产品数量)的参数。
我已经编写了以下函数来实现这一点,但在完整数据的情况下,我的函数无法正常工作,并且它给了我错误,例如 - 登录失败,签名不匹配。
def get_data(userid, api_key, action, pagination=True):
timeformat = datetime.datetime.now().replace(microsecond=0).isoformat() + '+08:00'
endpoint = 'https://example.com'
page_json = {}
# set required parameters for this api
parameters = {
'UserID': userid,
'Version': '1.0',
'Action': action,
'Format': 'JSON',
'Timestamp': timeformat
}
if pagination:
page = 0
parameters['Limit'] = 500
while True:
parameters['Offset'] = 500 * page
# set the required cryptographic signature
concatenated = urllib.parse.urlencode(sorted(parameters.items()))
parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest()
page += 1
try:
response = requests.get(endpoint, params=parameters)
page_json = response.json()
except requests.exceptions.ConnectionError:
print("Connection refused!")
sleep(5)
else:
try:
concatenated = urllib.parse.urlencode(sorted(parameters.items()))
# set the required cryptographic signature
parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest()
response = requests.get(endpoint, params=parameters)
page_json = response.json()
except requests.exceptions.ConnectionError:
print("Connection refused!")
sleep(5)
return page_json
在完整数据的情况下,我似乎没有正确拟合我的签名参数行。我打印了concatenated 的值,看起来像-
第 1 页 连接:: Action = GetProducts&Format = JSON&LIMIT = 500和偏移= 500和签名= 3D9CD320A4BF816AEA828B9392D2D5A27CD584B3A337338909C0AB161A101C和时间戳= 2018-05-26T12%3A58%3A38%2B08%3a38%2b08%3a00&userid = contact%40example.com.sg&version = 1.0 尝试:{'ErrorResponse':{'Head':{'ErrorCode':'7','ErrorMessage':'E7:登录失败。签名不匹配','ErrorType':'Sender','RequestAction':'GetProducts','RequestId':'0bb606c015273197313552686ec46f'}}}
第 2 页 连接:: Action = GetProducts&Format = JSON&LIMIT = 500和Offset = 1000&Signature = 1000和签名= C1bda1a5ab21c4e4182cc82ca7ba87cb9fc6c5f24c36f9bb006f9da906cf7083和时间戳= 2018-05-26T12%3a58%3a38%2b08%3a00&userid = contact%40example.com.sg&version = 1.0 尝试:{'ErrorResponse':{'Head':{'ErrorCode':'7','ErrorMessage':'E7:登录失败。签名不匹配','ErrorType':'Sender','RequestAction':'GetProducts','RequestId':'0bb606c015273197321748243ec3a5'}}}
能否请您查看我的函数并帮助我找出我写错了什么以及应该是什么样子?
【问题讨论】:
-
我认为您在循环中使用了包含 Signature 的相同字典,因此第一个请求正常,但后续请求失败,因为签名错误。尝试在每次迭代时打印
concatenated。 -
是的,它实际上正在发生-
-
@Norrius..我添加了印刷价值。由于我们为每个请求设置不同的偏移量,因此签名也将更改。那么你的意思是什么?
-
请查看我的代码,让我知道如何才能使它正确?
-
看到你根据
concatenated计算签名,我不认为之前迭代的签名应该在那个dict中。
标签: python api python-3.6