Python

【Python】requestsのレスポンスのエラー判定を行う方法

PythonにはHTTPのやり取りをするための便利なライブラリとしてrequestsがある。

GETでqueryも簡単にできるし、POSTでFORMデータを送信したりも簡単にできる。

リクエスト送信でも色々簡単にできるが、レスポンスも色々と便利になっている。

レスポンスに対しては、正常か異常かの判定をすることが多いと思うが、その中でも400番台以降といった大きなくくりだったり、特定のコード番号を指定しての判定ができる。

レスポンスのHTTPステータスコード確認方法

requestsは、getやpostなどでリクエストを送った際のレスポンスはResponseクラスで返ってくる。

ステータスコードはstatus_codeで取得できる。

また、requests.codesに200や404などのコードが用意されているため、これらと比較することで特定のステータスコードに該当するか、判定することができる。

import requests

r = requests.post(url, params=params)

# ステータスコードが200か判定
if r.status_code == requests.codes.ok:
    do something
# ステータスコードが201か判定
elif r.status_code == requests.codes.created:
    do something
# ステータスコードが404か判定
elif r.status_code == requests.codes.not_found:
    do something

resuests.codesに用意されているステータスコード

用意されているステータスコードの詳細は以下のソースに記載されている。

https://github.com/psf/requests/blob/main/requests/status_codes.py

ステータスコード判定によく使いそうなコードは以下の通り、

正常系

200ok, okay, all_ok, all_okay, all_good, \\o/ , ✓
201created
202accepted
204no_content

200には色々な書き方があるが、okを使うのが簡単で無難か。

リダイレクト系

301moved_permanently, moved, \\o-
302found

クライアントエラー系

400bad_request, bad
401unauthorized
403forbidden
404not_found, -o-
405method_not_allowed, not_allowed
406not_acceptable
408request_timeout, timeout
409conflict

サーバーエラー系

500internal_server_error, server_error, /o\, ✗
501not_implemented
502bad_gateway
503service_unavailable, unavailable
504gateway_timeout
505http_version_not_supported, http_version

特定のステータスコードを拾って何か処理をしたい場合は、上記のコードを参考に判定すれば良い。

エラー系レスポンスをまとめて判定する方法

個別でなく、まとめて判定できればそれでOKという場合、400番台と500番台をまとめて例外を発生させることもできる。

try:
    r = requests.get(url, params=params)
    # ステータスコードが400番台、500番台の場合はHTTPError発生
    r.raise_for_status()
    
except HTTPError as e:
    raise e

raise_for_status()を使うことでrequestsで定義されているHTTPErrorという例外が返ってくる。

例外の継承関係は

IOError -> RequestException -> HTTPError

となっているので、IOErrorなどでも拾える(でもHTTPErrorの方が分かりやすい)

あまり良くない正常系の判定方法

Responseにはokというプロパティが用意されており、

raise_for_status()でHTTPErrorが発生した場合はFalse、

発生しなかった場合はTrueが返ってくる。

requests.codes.okがステータスコード200を指すが、「ok」プロパティはステータスコードが200かどうかをチェックするものではなく、400番台、500番台かどうかをチェックするものである。

r = requests.get(url, params=params)

# 400番台、500番台の場合はFalse。それ以外の場合はTrue
if r.ok:
    # ステータスコード200以外も入ってくるので、想定外のことが起きる可能性が高い
    do something

個人的には「ok」と書いてると、200か201ぐらいかなとか思ってしまうが、実際はそれ以外もありうるので、あまり使わない方が良いと思う。

requestsでGETやPOSTをする方法

GETやPOSTリクエストを送信する方法は以下の記事を参照。