Python urllib httpメソッド

Python学習【365日チャレンジ!】159日目のマスターU(@Udemy11)です。

先日釣りにいった地域のコンビニによった時に、あまりにもびっくりする衝撃の出来事がありました。

それがこれ!

と画像を入れようと思ったのですがあまりにも衝撃すぎる画像になるのでやめておきます。

コンビニの入り口ってガラス張りで中が見えますよね。でもそのコンビニは一面真っ黒なつぶつぶが張り付いていて、中が見えないんです。

その正体は、なんと羽アリで、想像を絶するくらいの数の羽アリがガラス一面に張り付いているではありませんか!

さらに、ガラスに向かって飛んでいくちょっと大きめの物体。

よく見るとクワガタがガラスに衝突して地面でもがいていました。

私が住んでいるところも田舎ですが、これほどの数の虫、それも普通にクワガタが飛んでくるようなコンビニを見たのは初めてで、かなり衝撃を受けてしまいました。

しかも地元の人はそれが普通のようで、ビビってる私の横を普通に店内に入っていきました。

ということで、今日もPython学習を始めましょう。

昨日の復習

昨日は、代表的なHTTPメソッドについて学習しました。

普段わたしたちが利用しているWebページやTwitter、Facebookなどでも普通に活用されていて、GET、POST、PUT、DELETEの4つでほとんどの処理ができました。

きちんと理解するには時間がかかりそうですが、基本を押さえてさわってみることが大切です。

代表的なHTTPメソッドの詳細については、昨日の記事をごらんください。

今日は、そんなHTTPメソッドをPythonで扱うurllibについて学習しましょう。。

urllibとは

urllibは、URLを扱ういくつかのメソッドを集めたパッケージで、Pythonの標準ライブラリに組み込まれています。

urllib.requesturllib.errorurllib.parseurllib.robotparserなどがありますが、その中でもURLを開いて読み込むためのrequestモジュールを使ってHTTPメソッドを利用していきます。

https://httpbin.org/

こちらのサイトは、トップページにA simple HTTP Request & Response Service.と書かれているように、テストとしても利用できるシンプルなHTTPリクエストに対してレスポンスを返してくれるサイトです。

Web開発において、送信したHTTPメソッドのパラメータやヘッダーがきちんと送信されているか確認するために使えるサイトです。

何が有用なのか現時点ではいまいちピンと来ませんが、こちらの記事でhttpbinの有用性が紹介されているので、参考にどうぞ。

GET

GETメソッドをテストするには、https://httpbin.org/getを利用します。

json形式のファイルを扱うので、urllib.requestと合わせてjsonをインポートしてから、URLを指定し、リクエストした内容をutf-8にエンコードしてタイプと一緒に出力します。

import json
import urllib.request

url = 'https://httpbin.org/get'
with urllib.request.urlopen(url) as f:
    r = json.loads(f.read().decode('utf-8'))
    print(r)
    print(type(r))

出力結果

{'args': {}, 'headers': {'Accept-Encoding': 'identity', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.7', 'X-Amzn-Trace-Id': 'Root=1-5f0daodbf-8e38720037865fa06ce11c0e'}, 'origin': '111.84.48.111', 'url': 'https://httpbin.org/get'}
<class 'dict'>

Pythonで扱えるように、6行目でjson.loads()を使ってjson形式を辞書型に変換していますが、このjson.loads()を入れずに実行すると、次のような出力になります。

{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.7", 
    "X-Amzn-Trace-Id": "Root=1-5f0daodbf-8e38720037865fa06ce11c0e"
  }, 
  "origin": "111.84.48.111", 
  "url": "https://httpbin.org/get"
}
<class 'str'>

jsonファイルの標記になり、タイプは辞書型ではなくstrになっています。

GETメソッドは、URLの後ろに?をつけて、パラメーターを指定することができます。

例えば、{'key1': 'value1', 'key2': 'value2'}というパラメーターを付け足してリクエストを送る場合は次のように記述します。

import json
import urllib.request

payload = {'key1': 'value1', 'key2': 'value2'}

url = 'https://httpbin.org/get' + '?' + urllib.parse.urlencode(payload)
with urllib.request.urlopen(url) as f:
    r = json.loads(f.read().decode('utf-8'))
    print(r)

出力結果

{'args': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept-Encoding': 'identity', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.7', 'X-Amzn-Trace-Id': 'Root=1-5f0daodbf-8e38720037865fa06ce11c0e'}, 'origin': '111.84.48.111', 'url': 'https://httpbin.org/get?key1=value1&key2=value2'}

4行目で変数payloadに辞書型データを代入して、6行目でURLに?を付け足したあと、urllib.parse.urlencode(payload)によって、戻り値が&(アンパサンド)で区切られたkey=valueのペアで構成される文字列を追加しています。

出力結果では、argspayloadに代入した辞書型データと最後のurlhttps://httpbin.org/get?key1=value1&key2=value2になっているのがわかります。

httpbin.orgは、クライアントから送ったリクエストがどのように受け止められているかを確認するためのものなので、このサイトでテストをしてから実際の運用を始めるという使い方をされているようです。

POST

次にPOSTメソッドの使い方をみてみましょう。

import json
import urllib.request

payload = {'key1': 'value1', 'key2': 'value2'}
payload = json.dumps(payload).encode('utf-8')
req = urllib.request.Request('https://httpbin.org/post', data=payload, method='POST')
with urllib.request.urlopen(req) as f:
    print(json.loads(f.read().decode('utf-8')))

5行目で最初に定義した辞書型のpayloadを上書きしています。

辞書型をutf-8でエンコードしたJSON形式に上書きしたあと、6行目でpayloadを引数としたPOSTをhttps://httpbin.org/postにリクエストするオブジェクトreqを生成し、7行目でリクエストを送っています。

最後はコンソールに出力するためのコードになります。

出力結果は次のようになります。

{'args': {}, 'data': '', 'files': {}, 'form': {'{"key1": "value1", "key2": "value2"}': ''}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '36', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.7', 'X-Amzn-Trace-Id': 'Root=1-5f0daodbf-8e38720037865fa06ce11c0e'}, 'json': None, 'origin': '111.84.48.111', 'url': 'https://httpbin.org/post'}

formpayloadの値が入っているのがわかります。

PUT

続いてPUTメソッドを使ってみます。

import json
import urllib.request

payload = {'key1': 'value1', 'key2': 'value2'}
payload = json.dumps(payload).encode('utf-8')
req = urllib.request.Request('https://httpbin.org/put', data=payload, method='PUT')
with urllib.request.urlopen(req) as f:
    print(json.loads(f.read().decode('utf-8')))

出力結果

{'args': {}, 'data': '', 'files': {}, 'form': {'{"key1": "value1", "key2": "value2"}': ''}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '36', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.7', 'X-Amzn-Trace-Id': 'Root=1-5f0daodbf-8e38720037865fa06ce11c0e'}, 'json': None, 'origin': '111.84.48.111', 'url': 'https://httpbin.org/put'}

POSTとほぼ同じコードになりますが、6行目のURLのpostputに、method='POST'method='PUT'に変わっています。

出力結果は、最後のURL以外、POSTと同じですね。

DELETE

最後にDELETEメソッドを使ってみます。

import json
import urllib.request

payload = {'key1': 'value1', 'key2': 'value2'}
payload = json.dumps(payload).encode('utf-8')
req = urllib.request.Request('https://httpbin.org/delete', data=payload, method='DELETE')
with urllib.request.urlopen(req) as f:
    print(json.loads(f.read().decode('utf-8')))

出力結果

{'args': {}, 'data': '', 'files': {}, 'form': {'{"key1": "value1", "key2": "value2"}': ''}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '36', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.7', 'X-Amzn-Trace-Id': 'Root=1-5f0daodbf-8e38720037865fa06ce11c0e'}, 'json': None, 'origin': '111.84.48.111', 'url': 'https://httpbin.org/delete'}

POST、PUTとほぼ同じコードですが、6行目のURLがdeleteに、method'DELETE'に変わっています。

出力結果は最後のURL以外は、POST、PUTと同じ結果になっています。

具体的な利用シーン?

urllibを使ったHTTPメソッドの操作を学習しましたが、最終的にこれをどこで生かすのかぼんやりとしか理解できていません。

Webサイトに要求をして返ってきたデータを表示したり、値を使ってなにかの処理をしたりするわけですが、この先のイメージがまだできないのが現状です。

イメージ的には、楽天やAmazonのサイトから商品を検索して、レビューを取得して自分のサイトに表示をするとか、いくつかのECサイトから同じ商品の価格を取得して比較するなど、この部分で使われているだろうなということはなんとなくわかるのですが、いざ自分でどのようなサービスができるかというと具体的に思い浮かびません。

普段、何気なく利用しているサービスの裏で、このようなプログラムが動いているのがわかれば、あとはそれを理解していくだけですが、やっぱり数をこなさないとだめですね。

先は長いですが、一歩一歩進んでいこうと思います。

それでは明日もGood Python!