それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

python3 urllib でPOST/GET/PUT と JSON 送信

python3 の urllib を使う。

ひさしくpython2.7 だし全然不満がないのですが。python3.6 の文字列展開とjinja2 が便利そうだしそろそろ python3 使ってみようと思い立って、まずは基本的なリクエストを投げるところから。

urllib.request で各種リクエストを作る

urllib.request は 公式ドキュメントにすら Requests を使ったら?と書かれてたりする。 まぁ、そうなんだけど。py3から使い方も変わったしおさらいしておくことにする。

基本的なリクエストの流れ

import urllib,urllib.request
url = 'https://t.co'
req = urllib.request.Request(url=url)
f = urllib.request.urlopen(req)
print(f.read().decode('utf-8'))

Request を作って urlopen(request) するのが基本的な流れ。

もちろんGETするだけならもっとシンプルに使える

urllib.request.urlopen(url)

でも、getして終わりってわけじゃないよね。プログラム言語を使い込んでいくならかならず POST/GET/PUT と JSON送信なんかが出て来る。

各種サンプルを試してみた

#!/usr/bin/env python3

import http.client
import urllib
import urllib.request


## phpinfo の内容をjson で返してくれるURL
url = 'http://[::1]/~takuya/info_json.php'

## GET SAMPLE
def sample_get():
  req = urllib.request.Request(url=url)
  f = urllib.request.urlopen(req)
  print(f.read().decode('utf-8'))

## POST SAMPLE
def sample_post():
  req = urllib.request.Request(url=url, data=b'var=1')
  f = urllib.request.urlopen(req)
  print(f.read().decode('utf-8'))

## POST with Custom HEADER
def sample_post_with_header():
  headers={
    'Content-type':'application/json'
  }
  req = urllib.request.Request(url=url,headers=headers, data=b'{ "a" : 1  }')
  f = urllib.request.urlopen(req)
  print(f.read().decode('utf-8'))

## POST json with Custom HEADER
def sample_post_with_header_and_json():
  headers={
    'Content-type':'application/json'
  }
  json_str='{"a":1}'
  req = urllib.request.Request(url=url,headers=headers, data=json_str.encode('utf-8'))
  f = urllib.request.urlopen(req)
  print(f.read().decode('utf-8'))

## PUT json with Custom HEADER
def sample_put_with_header_and_json():
  headers={
    'Content-type':'application/json'
  }
  json_str='{"a":1}'
  req = urllib.request.Request(url=url,headers=headers, data=json_str.encode('utf-8'), method='put')
  f = urllib.request.urlopen(req)
  print(f.read().decode('utf-8'))

まとめ

HTTP(s)のリクエストを送信するときにアレコレする場合は、すべてurllib.request.Request を作って、それを open することになるとわかった。

引数増やすだけで対応できるので楽ですねぇ。

urllib.request.Request(url=url) # simple GET
urllib.request.Request(url=url, data=b'var=1') # POSTする
urllib.request.Request(url=url,headers=headers, data=b'var=1') # HEADERつける
urllib.request.Request(url=url,headers=headers, data=json_str.encode('utf-8'), method='put')

ハマりどころは、POSTデータ byte 型になるところ

data=b'var=1'
# または
data=str.encode('utf-8')

などとやっておかないとエラーになる。油断してると忘れそうになる。

これで各種APIを叩くのが楽になりますね。

参考資料

https://docs.python.org/3.4/library/urllib.request.html#module-urllib.request