29
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pythonでAPIを叩いた時にSSL認証エラーでハマったときの対処法

Posted at

API使ってデータ取得しようとした際にハマったのでメモ。

環境はpython3.6.4。
以下ハマったスクリプト。

import json
import urllib.request, urllib.error
 
#リクエストするアドレス
request_url="***********************"
 
#検索開始日付
PARAM_START_DATE="2018-09-01"
 
#検索終了日付
PARAM_END_DATE="2018-09-30"
 
#API-KEYのセット
API_KEY="***********************"
 
headers = {'x-api-key': API_KEY, "Content-Type":"application/json"}
request_json={
"start_date":PARAM_START_DATE,
"end_date":PARAM_END_DATE
}
 
req = urllib.request.Request(url=request_url, headers=headers, data=json.dumps(request_json).encode())
f = urllib.request.urlopen(req)
response = f.read()
f.close()

上記スクリプトを流したところSSL認証エラー。

urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

verify = Falseを設定すれば解決できるようだが、最終的にはお仕事で使う必要があり、あまりやりたくなかったので別の解決策を模索。
参考 → Python requests で SSLError が起きて毎回ググってるのでまとめた

諸々調べた所、上記のエラーはpython2.7.9以降で出現するという記事を見たので、試しにpython2.7.8にバージョンを落として実行してみたところ、今度は以下のエラー。
SSL証明書が正しくないサイトに対してPythonでアクセスする

urlopen error [Errno 1] _ssl.c:510: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

バージョン下げればいいとかそういう問題ではない模様。
handshakeについて → SSL/TLS(SSL3.0~TLS1.2)のハンドシェイクを復習する

#####解決策
SSLContextを使えば認証方法を設定する事が可能とのことなので試してみる。
公式リファレンス → https://docs.python.jp/3/library/ssl.html#ssl.SSLContext


import json
import urllib.request, urllib.error

#認証方法をTLSv1に指定
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 
#リクエストするアドレス
request_url="***********************"
 
#検索開始日付
PARAM_START_DATE="2018-09-01"
 
#検索終了日付
PARAM_END_DATE="2018-09-30"
 
#API-KEYのセット
API_KEY="***********************"
 
headers = {'x-api-key': API_KEY, "Content-Type":"application/json"}
request_json={
"start_date":PARAM_START_DATE,
"end_date":PARAM_END_DATE
}
 
req = urllib.request.Request(url=request_url, headers=headers, data=json.dumps(request_json).encode())
#context=TLSv1に指定
f = urllib.request.urlopen(req,context=context)
response = f.read()
f.close()

これで動きました。

29
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?