2016/02/19更新

[Python] HTTP通信でGetやPostを行う

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
本日はPythonでHTTP通信を行う色々な方法をブログに残したいと思います。僕自身、http通信の実装を良く書きますが、全部は覚えきれていないので、備忘録の意味も込めたブログです。

※注意 本ブログはPython3系を対象にしています(2系は実装が異なります)。

画像


目次




最もシンプルな方法

最も簡単にhttp通信を行うなら、以下のようにすることでGET通信を行うことができます。
import urllib.request
with urllib.request.urlopen("http://www.yoheim.net") as res:
   html = res.read().decode("utf-8")
   print(html)
urllib.request.urlopen関数を使えば、シンプルなGET通信を行うことができます。resはResponseオブジェクトで、通信結果を保持しています。



GETパラメータを付けて通信する

GETパラメータを付与する場合には、URLに付与することで、パラメータ付きのGET通信を行うことができます。
import urllib.request, urllib.parse
params = {
    "name": "yoheim",
    "age": 29,
    "comment": "ああああ"
}
p = urllib.parse.urlencode(params)
url = "http://www.yoheim.net/?" + p
print(url)
# => http://www.yoheim.net/?age=29&name=yoheim&comment=%E3%81%82%E3%81%82%E3%81%82%E3%81%82

with urllib.request.urlopen(url) as res:
   html = res.read().decode("utf-8")
   print(html)


# または簡単なパラメータの場合には、自分でつけちゃっても良い
url = "http://www.yoheim.net/blog.php?q=%d" % 20160203
print(url)
# => http://www.yoheim.net/blog.php?q=20160203
ここでのポイントは、urllib.parse.urlencodeを使って、dict型からkey=value型に変換して、またurlエンコードもしちゃうところでしょうか。これを使うことで、パラメータ付きのGET通信を行うことができます。



POST通信を行う

POSTを行う場合には、urllib.request.urlopen関数の引数にデータを追加することで、POST通信を行うことができます。
import urllib.request, urllib.parse
data = {
    "name": "yohei",
    "age": 30,
    "comment": "あああ"
}
# ここでエンコードして文字→バイトにする!
data = urllib.parse.urlencode(data).encode("utf-8")
with urllib.request.urlopen("http://www.yoheim.net/", data=data) as res:
   html = res.read().decode("utf-8")
   print(html)
文字→バイトに変換したデータを引数に渡すことで、POST通信を行うことができます。なお、パラメータが不要なPOST通信の場合は空データを渡します。
import urllib.request, urllib.parse
with urllib.request.urlopen("http://www.yoheim.net/", data=b"") as res:
   html = res.read().decode("utf-8")
   print(html)



リクエストヘッダを付与する

何か外部のAPIを使う場合には、リクエストヘッダーに特定の情報を付与する必要がよくあります。HTTPリクエストに任意のパラメータを付与する場合は、以下のように実装します。
import urllib.request, urllib.parse

# GET通信の場合
req = urllib.request.Request("http://www.yoheim.net/")
req.add_header("X-CUSTOM-HEADER", "this_is_custom_header")
with urllib.request.urlopen(req) as res:
    html = res.read().decode("utf-8")

# POST通信の場合(dataパラメータを付与)
req = urllib.request.Request("http://www.yoheim.net/")
req.add_header("X-CUSTOM-HEADER", "this_is_custom_header")
data = urllib.parse.urlencode({"key":"value"}).encode("utf-8")
with urllib.request.urlopen(req, data) as res:
    html = res.read().decode("utf-8")
    print(html)

# 色々なヘッダーをまとめて付与
headers = {
    "X-header1" :"aaa",
    "X-header2" :"bbb",
    "X-header3" :"ccc"
}
req = urllib.request.Request("http://www.yoheim.net/", headers=headers)
with urllib.request.urlopen(req) as res:
    html = res.read().decode("utf-8")
    print(html)
Requestオブジェクトを作ることで、リクエストを色々とカスタマイズすることができます。



Basic認証に対応する

Basic認証も上述のリクエストヘッダー付与で対応することができます。
import urllib.request, urllib.parse
import base64

usr = "my user name"
pwd = "my password"

base64string = base64.encodestring(('%s:%s' % (usr, pwd)).encode("utf-8"))[:-1]
headers = {
    "Authorization": "Basic %s" % base64string.decode("utf-8")
}
req = urllib.request.Request("http://www.yoheim.net/", headers=headers)
with urllib.request.urlopen(req) as res:
    html = res.read().decode("utf-8")
    print(html)



Cookieを有効化する

今までの方法の場合、レスポンスにSet-Cookieが含まれていても、その後のリクエストでそれが使われません。認証が必要なページをクローリングする場合には、一連のリクエストでクッキーを引き継ぐ必要があります。それについては別のブログで書きましたので、そちらをご参照ください。

- [Python] HTTP通信にCooki処理を追加して、はてなにログインする



レスポンスヘッダの取得

TwitterなどのAPIの場合、レスポンスヘッダーに残りの有効回数などが含まれます。それらを取り出すには以下のように行います。
import urllib.request
with urllib.request.urlopen("http://www.yoheim.net/") as res:
    response_headers = res.info()
    remain_count = response_headers["Remain-Count"]
    print(remain_count)



参考資料

Python3系の以下のリファレンスを参照しました。他にもRequestオブジェクトを色々と操作したり、上記以外の通信方法があったりと色々と情報がいっぱいありますので、よく参照しています。

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



最後に

今日はPython3系でHTTP通信を行う方法をブログに書きました。このようにブログに書いておかないと忘れちゃうんですよね〜。自分の頭脳の一部としてブログはよく使ってますw。

本ブログでは、フロントエンド・Python・機械学習を中心に発信していきます。気になった方はぜひ、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。