こんちには Keita_Nakamoriです。
Python標準モジュールのurllibを使ってHTTPメソドを実行してみましょう。
IT用語 (予備知識として)
HTTPメソド
クライアントからサーバーに命令をする具体的なやり方のことです。
基本の4つの操作
GET:データを参照する
POST:データを新規登録する(パスワードを見えないように送るとき)
PUT:データを更新する
DELETE:データを削除する
その他 HEAD OPTIONS TRACE PATCH LINK UNLINK と色々あります。
REST
-REpresentational State Transfer
”表現文の転送”ということでしょうか。Webサービスに対してデータをやり取りする際の取り決め、というかコンセプトです。
RESTに従ったWebサービスは、HTTPメソドの形式でアクセスすることでデータの送受信を行えます。
REST APIという形でまとまっているWebサービスが多いので利用できます。
パケット通信
音声通話のように回線を占有するのではなく、
データを小さな単位に分割して送受信することで
複数のユーザーで同じ回線をシェアできる方法です。
送信されたデータは交換機の記憶メディアに一時的に蓄積されるので
相手の通信環境が悪くても、復帰したときにデータを受信できます。
ペイロード
パケット通信においてパケットに含まれるヘッダやトレーラなどの付加的情報を除いたデータ本体のことです。
パケットにはデータの転送先や転送経路などを制御するための情報を含むヘッダや、データの破損などを検査するトレーラなどの情報が、データそのもののほかに付加されて送られて来ます。
ペイロードは、こうした情報を対象に含めず、ユーザーが送信したいデータそのものを指し示す際に用いられます。
urllibモジュール
基本的な GET
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
# python 標準のurllib.request import urllib.request import json # RESTなURLの場合、後ろに/getを付けると HTTPメソドのgetができるように、予めそのwebサービスが用意してくれている。 url='http://httpbin.org/get' # urlopenでgetする with urllib.request.urlopen(url) as data: """print(data.read()) 一行で返ってくる b'{\n "args": {}, \n "headers": {\n "Accept-Encoding": "identity", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.6"\n }, \n "origin": "106.168.119.201, 106.168.119.201", \n "url": "https://httpbin.org/get"\n}\n' """ """print(data.read().decode('utf-8')) utf-8でデコードすると\nを改行と認識してくれる。 これはJson形式になっている { "args": {}, "headers": { "Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.6" }, "origin": "106.168.119.201, 106.168.119.201", "url": "https://httpbin.org/get" } """ # json.loadsでJSONをディクショナリとして読み込む dict_data = (json.loads(data.read().decode('utf-8'))) print(dict_data) """ {'args': {}, 'headers': {'Accept-Encoding': 'identity', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.6'}, 'origin': '106.168.119.201, 106.168.119.201', 'url': 'https://httpbin.org/get'} """ print(type(dict_data)) # <class 'dict'> ちゃんとディクショナリになっている |
パラメータを含んだGET
|
import urllib.request import json #ディクショナリ形式でパラメータを送ってみよう #送信するデータの中核の部分をIT用語でpyloadと呼ぶことがあります。 payload = {'aaa': '111', 'bbb': '222', 'ccc': '333'} # getでパラメータを送るときは #'?'でつないでurllib.parse.urlencode()したものを送ることになっている url = 'http://httpbin.org/get' + '?' + urllib.parse.urlencode(payload) print(url) # http://httpbin.org/get?aaa=111&bbb=222&ccc=333 with urllib.request.urlopen(url) as data: dict_data = (json.loads(data.read().decode('utf-8'))) print(dict_data) |
パラメータが見えないようにするPOST
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#パスワードや機密情報をおくる場合は、 #GETではなくてPOSTを使うことによって、 #見えないように送信することができます。 import urllib.request import json #ペイロード部分ももそのままではなくて json.dumps()に入れてエンコードしておく。 payload = {'aaa': '111', 'bbb': '222', 'ccc': '333'} payload = json.dumps(payload).encode('utf-8') # POSTとしてurlを送る url = 'http://httpbin.org/post' # pyloadはurlに'?'でつなぐのではなくて、引数にpyloadを入れる req = urllib.request.Request(url, data=payload, method='POST') with urllib.request.urlopen(req) as data: dict_data=json.loads(data.read().decode('utf-8')) print(dict_data) print(type(dict_data)) # <class 'dict'> |
PUT
|
# 同様に PUT は import urllib.request import json #PUTの場合もjson.dumps()が必要 payload = {'aaa': '111', 'bbb': '222', 'ccc': '333'} payload = json.dumps(payload).encode('utf-8') url = 'http://httpbin.org/put' # putに書き換える req = urllib.request.Request(url, data=payload, method='PUT')#PUTに書き換える with urllib.request.urlopen(req) as data: dict_data=json.loads(data.read().decode('utf-8')) print(dict_data) |
DELETE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
# 同様に DELETE は import urllib.request import json #PUTの場合もjson.dumps()が必要 payload = {'aaa': '111', 'bbb': '222', 'ccc': '333'} payload = json.dumps(payload).encode('utf-8') url = 'http://httpbin.org/delete' # deleteに書き換える req = urllib.request.Request(url, data=payload, method='DELETED')#DELETEに書き換える with urllib.request.urlopen(req) as data: dict_data=json.loads(data.read().decode('utf-8')) print(dict_data) """ HTTPError: HTTP Error 405: METHOD NOT ALLOWED """ |
ここで、HTTPError: HTTP Error 405: METHOD NOT ALLOWED とエラーになりました。DELETEは用意されていないようです。