PythonモジュールRequestsのHTTPステータスコードについて
はじめに
LambdaでURL監視をする際に使用したPython(Requests)について調べたことをご紹介したいと思います。
RequestsでHTTPステータスコードを取得する
成功の場合
>>> import requests >>> r = requests.get('http://httpbin.org/get') >>> r.status_code 200
簡易的にTrue,False判定する場合
>>> r.status_code 200 >>> r.status_code == requests.codes.ok True >>> r = requests.get('http://httpbin.org/status/404') >>> r.status_code 404 >>> r.status_code == requests.codes.ok False
4XX、5XX系のレスポンスの場合、例外を発生させることも可能
>>> r.raise_for_status() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/username/.pyenv/versions/3.6.1/lib/python3.6/site-packages/requests/models.py", line 935, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: http://httpbin.org/status/404
リダイレクトの場合
リダイレクトが発生するURLを取得した際に悩みました。
リダイレクト301のステータスコードを期待していましたが200が戻ってきました。
>>> r = requests.get('http://httpbin.org/status/301') >>> r.status_code 200
curlで確認しても301でしたがrequestsで200が戻ってきます。
$ curl -I http://httpbin.org/status/301 HTTP/1.1 301 MOVED PERMANENTLY Connection: keep-alive Server: meinheld/0.6.1 Date: Fri, 04 Aug 2017 19:28:40 GMT Access-Control-Allow-Credentials: true X-Powered-By: Flask Location: /redirect/1 X-Processed-Time: 0.000458955764771 Access-Control-Allow-Origin: * Content-Length: 0 Via: 1.1 vegur
ドキュメントを見ると以下記載がありました。
By default Requests will perform location redirection for all verbs except HEAD.
デフォルトではRequestsはリダイレクトに対応させているようです。
なのでcurlでいうと、-Lオプションをつけた挙動と同じですね。
$ curl -IL http://httpbin.org/status/301 HTTP/1.1 301 MOVED PERMANENTLY Connection: keep-alive Server: meinheld/0.6.1 Date: Fri, 04 Aug 2017 19:28:47 GMT Access-Control-Allow-Credentials: true X-Powered-By: Flask Location: /redirect/1 X-Processed-Time: 0.000839948654175 Access-Control-Allow-Origin: * Content-Length: 0 Via: 1.1 vegur HTTP/1.1 302 FOUND Connection: keep-alive Server: meinheld/0.6.1 Date: Fri, 04 Aug 2017 19:28:47 GMT Content-Type: text/html; charset=utf-8 Content-Length: 215 Location: /get Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true X-Powered-By: Flask X-Processed-Time: 0.00106191635132 Via: 1.1 vegur HTTP/1.1 200 OK Connection: keep-alive Server: meinheld/0.6.1 Date: Fri, 04 Aug 2017 19:28:47 GMT Content-Type: application/json Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true X-Powered-By: Flask X-Processed-Time: 0.000760793685913 Content-Length: 214 Via: 1.1 vegur
Requestsでリダイレクトを確認するには Response.history を使います。
>>> r = requests.get('http://httpbin.org/status/301') >>> r.history [<Response [301]>, <Response [302]>]
結果が古い順にリストで確認できます。
>>> r.history [<Response [301]>, <Response [302]>] >>> r.history[0] <Response [301]> >>> r.history[1] <Response [302]> >>> r.history[0].status_code 301 >>> r.history[1].status_code 302
リダイレクトさせずステータスだけ見たい場合は allow_redirects パラメータを使用します。
>>> r = requests.get('http://httpbin.org/status/301' ,allow_redirects=False) >>> r.status_code 301 >>> r.history []
Response.status_code で301が確認できます。
またリダイレクトはされなので、 r.history の結果は空です。
まとめ
今回はリダイレクトするURLを取得する際に悩んだのでステータスコードについて記載しました。
詳しくはドキュメント(以下参考URL) を見ていただきたいのですが
本ブログも参考になれば幸いです。
ではまた。