いくつかのAPIテストを実行し、入力されたURLを指定する関数を作成しようとすると、json応答が返されますが、HTTPエラーが応答の場合、エラーメッセージが返されます。
以前はurllib2を使用していましたが、代わりにリクエストを使用しようとしています。ただし、エラーに関係なく、exceptブロックは実行されないようです。
testURL = 'http://httpbin.org/status/404'
def return_json(URL):
try:
response = requests.get(URL)
json_obj = response.json()
return json_obj
except requests.exceptions.HTTPError as e:
return "Error: " + str(e)
上記を実行した結果...
<Response [404]>
応答で200以外のステータスコードの例外を発生させる場合は、response.raise_for_status()
を使用します。コードは次のようになります。
testURL = 'http://httpbin.org/status/404'
def return_json(URL):
response = requests.get(testURL)
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
# Whoops it wasn't a 200
return "Error: " + str(e)
# Must have been a 200 status code
json_obj = response.json()
return json_obj
これは他のソリューションよりも明らかにシンプルであり、ステータスコードを手動で確認する必要がないことがわかります。 HTTPError
をキャッチすることもできます。これはraise_for_status
が発生します。 RequestsException
をキャッチするのはよくありません。それはConnectionError
sやTimeoutError
sなどのようなものをキャッチします。これらのどれも、あなたがキャッチしようとしているものと同じことを意味しません。
注:これは受け入れられた回答ですが、 Ian's answer で説明されているように、response.raise_for_status()
を使用する必要があります以下(彼はrequests
モジュールのメンテナーの一人)。
これをどのように処理するかは、HTTPエラーとみなされるものによって異なります。ステータスコードはありますが、_200
_以外のすべてが必ずしも何らかのエラーがあることを意味するわけではありません。
お気づきのように、リクエストライブラリはHTTP応答の別の側面を考慮し、例外を発生させません。たとえば、HTTPステータス_302
_はFound
を意味しますが、応答には応答本文が含まれず、代わりにLocation
ヘッダーが含まれているため、リソースにアクセスする必要があります実際に欲しかった。
したがって、 _response.status_code
_ を調べて、実際のプロトコルエラーをキャッチしながら、その処理を行います_try..except
_付き。これらをキャッチするときは、実際に_requests.exceptions.RequestException
_をキャッチする必要があります。これは、これが他のすべての例外の ベースクラスrequests
モジュールが発生するためです。
したがって、次の3つのケースすべてを示す例があります。
200 OK
_応答200
_以外のステータス_import requests
test_urls = ['http://httpbin.org/user-agent',
'http://httpbin.org/status/404',
'http://httpbin.org/status/500',
'httpx://invalid/url']
def return_json(url):
try:
response = requests.get(url)
# Consider any status other than 2xx an error
if not response.status_code // 100 == 2:
return "Error: Unexpected response {}".format(response)
json_obj = response.json()
return json_obj
except requests.exceptions.RequestException as e:
# A serious problem happened, like an SSLError or InvalidURL
return "Error: {}".format(e)
for url in test_urls:
print "Fetching URL '{}'".format(url)
print return_json(url)
print
_
出力:
_Fetching URL 'http://httpbin.org/user-agent'
{u'user-agent': u'python-requests/2.1.0 CPython/2.7.1 Darwin/11.4.2'}
Fetching URL 'http://httpbin.org/status/404'
Error: Unexpected response <Response [404]>
Fetching URL 'http://httpbin.org/status/500'
Error: Unexpected response <Response [500]>
Fetching URL 'httpx://invalid/url'
Error: No connection adapters were found for 'httpx://invalid/url'
_
また、成功した応答を取得した場合はresponse.json()
によって例外が発生する可能性がありますが、それは単にJSONではないため、同様に説明することもできます。
注:_if not response.status_code // 100 == 2
_ビットは次のように機能します:_//
_演算子はいわゆる floor divisionを実行します ので、次の整数に切り捨てます(これは、Python 2.xの_/
_のデフォルトの動作ですが、Python 3.x、これは_/
_を浮動小数点除算に変更したため、_status // 100 == 2
_はすべての_2xx
_コードに当てはまります。
response.status_code
値を確認できます。 200
でない場合は、エラー状態であると見なし、独自の例外をスローできます。