Closed miyagin15 closed 5 years ago
他のパラメータが分かりませんが、
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/*クラス名*&limit=100", headers=headers)
ではなくて、
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/*クラス名*?limit=100", headers=headers)
ということはないでしょうか? &
ではなく ?
です。
迅速な回答ありがとうございます。
?limit=100としても HTTPError: HTTP Error 403: Forbidden というレスポンスになってしまいます。
headersは
headers = {
"X-NCMB-Application-Key" :"***",
"X-NCMB-Timestamp" :"***",
"X-NCMB-Signature" :"***",
"Content-Type" :"application/json"
}
上のようにしていて "X-NCMB-Signature" :"***"の値はニフクラREST APIツールのX-NCMB-Signatureを随時コピペしています limit数をいろいろ変えるたびにX-NCMB-Signatureの値が変わるため、 X-NCMB-Signatureはコピペしていますが エラーは変わりません。
X-NCMB-Timestamp
の値も変わっていますよね?署名の生成時にタイムスタンプも使っているので、アクセス時間が変わると署名も変わります。
REST APIツールのリクエスト部分をターミナルで実行して、そのまま結果が得られるならば、それをPython風にするだけで良いのですが。
以前使ってたプリセットを使ってるためか、X-NCMB-Timestampは変わっていませんでした。 新しくプリセットを作り、X-NCMB-Timestampも更新した状態で、pythonで動かしてみたのですが、
import urllib.request, urllib.parse
headers = {
"X-NCMB-Application-Key" :"****",
"X-NCMB-Timestamp" :"2019-08-18***",
"X-NCMB-Signature" :"***",
"Content-Type" :"application/json"
}
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login?limit=1000", headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
としていますが、
HTTPError: HTTP Error 403: Forbiddenが返ってきます
REST APIツールのほうを実行すると値が返ってくるのは確認しています。
またそのREST APIツールとheaderの値は同じことは確認しました
~~~~~~~~~~~~~~~
--data-urlencode 'limit=1000' \
https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login/
APIツールのほうと違うのはlimitがURLに入ってるか入ってないかぐらいかと思います。 limitを書かなければ100個データが取れるのは確認しています
何か考えられる原因はありますでしょうか?
limit=100
というパラメータが入れば、署名の文字列も変わってきます。その署名はlimitが書かれていない場合の署名です。
署名はクエリストリングやタイムスタンプなどによって異なるものが生成されます。
REST API ツール上でlimit数を変えたら署名の文字列をpythonにコピペしています。
わたしがやっていることは REST API ツールのほうでlimit数を変えたら、その都度、署名の文字列をコピーして
import urllib.request, urllib.parse
headers = {
"X-NCMB-Application-Key" :"****",
"X-NCMB-Timestamp" :"2019-08-18***",
"X-NCMB-Signature" :"*ここ*",
"Content-Type" :"application/json"
}
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login?limit=1000", headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
ここの署名にいれています。 ここでlimi数を150とか2000とか変えたときに、REST API ツールのほうでもlimit数を同じように変えて、署名の文字列が変わったのを確認してpythonにコピペしています。
limitがなしのときも同様にREST APIツールのほうでlimitを消して署名の文字列をコピーして
import urllib.request, urllib.parse
headers = {
"X-NCMB-Application-Key" :"****",
"X-NCMB-Timestamp" :"2019-08-18***",
"X-NCMB-Signature" :"*ここ*",
"Content-Type" :"application/json"
}
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login/", headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
としています。 これは予想通りに動くのですが、、
X-NCMB-Timestamp
の値も書き換えていますか?
はい書き換えています。
個人的に、urlが間違っているのかと思っています。 クエリパラメータをつけない場合はうまくデータが取れるので
--data-urlencode 'limit=1000' \
ここをうまくURLエンコードできていないのかと。
新しく
params = {
'limit':1000,
}
params = {
'limit':1000,
}
url="https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login"
req = urllib.request.Request("{}?{}".format(url, urllib.parse.urlencode(params)),headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
としてもHTTP Error 403: Forbiddenとなります
'{}?{}'.format(url, urllib.parse.urlencode(params),headers=headers))を出力すると 'https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login?limit=1000' となりあっているはずなのですが。
https://qiita.com/hurutoriya/items/7156874ed2256c06a514
を見ると、渡し方が違うと言うことはないでしょうか?クエリストリングなので合っているように思うのですが。後、Pythonのコードに変換せず、curlコマンドそのまま実行した時には意図した結果が返ってくるのでしょうか。もし返ってくるならば、署名の問題ではないように思います。
書かれているコードを試してみた限りでは、 https://mbaas.api.nifcloud.com/2013-09-01/classes/Example?limit=1000
で取得できます。書き換えたのは X-NCMB-Signature
の値とURLです。REST APIツールで取れる値です。
違いはURLと署名だけのはずです。
import urllib.request, urllib.parse
headers = {
"X-NCMB-Application-Key" :"b347bafb25296ae896e06684068574f4332e2526626f78b475e799ca5882901e",
"X-NCMB-Timestamp" :"2019-08-20T02:42:44.659Z",
"X-NCMB-Signature" :"KGKUqHxHW3XuVSSC/YDb4UZEJx9DLQQ0G0nAjGwpXSA=",
"Content-Type" :"application/json"
}
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/Example", headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
import urllib.request, urllib.parse
headers = {
"X-NCMB-Application-Key" :"b347bafb25296ae896e06684068574f4332e2526626f78b475e799ca5882901e",
"X-NCMB-Timestamp" :"2019-08-20T02:42:44.659Z",
"X-NCMB-Signature" :"yZF24KzAo3Y2gO1eyiAmTUjmo1tIwplTnOi72vtiD74=",
"Content-Type" :"application/json"
}
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/Example?limit=1000", headers=headers)
with urllib.request.urlopen(req) as res:
html = res.read().decode("utf-8")
print(html)
pythonで試していただいてありがとうございます。
req = urllib.request.Request("https://mbaas.api.nifcloud.com/2013-09-01/classes/No_Login/?limit=1000", headers=headers) とすることで値が取得できました クラス名の後に/?limit=1000としました。 なぜこうすることで取得できるようになったのかはわかりません。 もしなにかご存じでしたら教えてください。
何回も質問をしてしまってお手数をおかけしました。助かりました。
データストアにpythonでアクセスすることがでてき、100件のデータを取得することができました.
limitを設定して取得数を変えようとしているのですが、うまくできません。 現在
として取得ができています。 しかし
とすると403 Forbiddenが返ってきます。 リクエストするURLが間違っているのでしょうか?
ちなみに REST APIツールのほうでクエリにlimit =100を設定したときのsignatureをheaderに設定しています