pythonでHTTPリクエストを送信するには...requests?
いえいえ、PycURLだってあります。
細かくいろいろあれこれするときはPycURLだよねって人、気持ちわかります
たまには趣向を変えましょう。
ここではPycURLを使っていろいろいろするためのやり方を書いていきます。
PycURLとは...
http://pycurl.io/
https://pypi.python.org/pypi/pycurl
PycURLはlibcurlのためのPythonインタフェースです。大概requestsでもおんなじことができる(はず)。
インストール
pip でインストールします。
$ pip install pycurl
http://pycurl.io/docs/latest/index.html#installation にインストールの説明があります。
サーバには https://gist.github.com/TakesxiSximada/d2792ef0b6ef2947402cca008b0323ea を使います。server.pyをダウンロードして以下を実行してください。
$ python server.py
メソッドの設定
REST APIのメソッドを指定してリクエストを送信します。
GET
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.perform()
実行結果
デフォルトの挙動ではrespose bodyは標準出力に書き出されます。
$ python get_example_default.py
OK
メソッドを指定しない場合はGETになります。
メソッド名を明示的に指定したい場合は Curlオブジェクトに pycurl.CUSTOMREQUESTを設定します。
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'GET')
curl.perform()
POST
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'POST')
curl.perform()
POSTFIELDを設定した場合はデフォルトでPOSTになります。
import urllib.parse
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
field_data = urllib.parse.urlencode({'key': 'value'})
curl.setopt(pycurl.POSTFIELDS, field_data)
curl.perform()
PUT
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'PUT')
curl.perform()
PATCH
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'PATCH')
curl.perform()
HEAD
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'HEAD')
curl.perform()
DELETE
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'DELETE')
curl.perform()
OPTIONS
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.CUSTOMREQUEST, 'OPTIONS')
curl.perform()
詳細情報の表示
pycurl.VERBOSEをTrueで設定すると実行時の詳細情報を取得できます。
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.VERBOSE, True)
curl.perform()
実行結果
$ python verbose.py
* Rebuilt URL to: http://127.0.0.1:8000/
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: PycURL/7.43.0 libcurl/7.43.0 OpenSSL/1.0.2d zlib/1.2.8
Accept: */*
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.5.0
< Date: Sat, 21 May 2016 08:26:41 GMT
<
OK
* Closing connection 0
User Agentの変更
pycurl.USERAGENTでUserAgentを設定できます。
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.VERBOSE, True)
curl.setopt(pycurl.USERAGENT, 'yay (^-^)/~')
curl.perform()
実行結果
$ python set_ua.py
* Rebuilt URL to: http://127.0.0.1:8000/
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: yay (^-^)/~
Accept: */*
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.5.0
< Date: Sat, 21 May 2016 08:37:27 GMT
<
OK
* Closing connection 0
UserAgentはfake-userangetを使うと楽かも。。。
UserAgentを設定するときはいつもfake-useragetを使っているので一応書いておきます。
インストール
$ pip install fake-useragent
PycURLにfake-useragentを使ってChromeのUserAgentを設定する
fake_useragent.UserAgent().chrome でchromeのUAが取得できます。
import pycurl
import fake_useragent
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://127.0.0.1:8000')
curl.setopt(pycurl.VERBOSE, True)
ua = fake_useragent.UserAgent()
curl.setopt(pycurl.USERAGENT, ua.chrome)
curl.perform()
実行結果
$ python set_ua_fakeua.py
* Rebuilt URL to: http://127.0.0.1:8000/
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/4E423F
Accept: */*
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.5.0
< Date: Sat, 21 May 2016 08:43:20 GMT
<
OK
* Closing connection 0
分割ダウンロード
ファイルを途中からダウンロードしたりしたいこと...ありますよねー。
あるでしょ?
あるんですよ。
うん、あるある。
pycurl.RESUME_FROMを設定すると設定したbyte以降からダウンロードできます。
resumeはサーバ側が対応してないとダメなので、gistのデータを途中からダウンロードしてみます。
import pycurl
curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'https://gist.githubusercontent.com/TakesxiSximada/d2792ef0b6ef2947402cca008b0323ea/raw/82d677309084d66247a15ce1640bac44a4b23248/server.py')
curl.setopt(pycurl.VERBOSE, True)
curl.setopt(pycurl.RESUME_FROM, 100)
curl.perform()
プログレスバーの表示
プログレスバーは progressbar パッケージを使うと楽なのでそれを使ってみます。
https://pypi.python.org/pypi/progressbar
インストール
$ pip install progressbar
簡単なprogressbarを表示
import io
import pycurl
import progressbar
class PluggableProgress:
def __init__(self, progress_plugin):
self.progress_plugin = progress_plugin
def __call__(self, total_to_download, total_downloaded,
total_to_upload, total_uploaded):
if total_to_download:
percent = int(total_downloaded / total_to_download * 100)
self.progress_plugin.update(percent)
progress_plugin = progressbar.ProgressBar(max_value=progressbar.UnknownLength)
progress = PluggableProgress(progress_plugin)
fp = io.BytesIO()
curl = pycurl.Curl()
curl.setopt(pycurl.URL, '大きめのファイルのURL') # noqa
curl.setopt(pycurl.NOPROGRESS, 0)
curl.setopt(pycurl.PROGRESSFUNCTION, progress)
curl.setopt(pycurl.WRITEDATA, fp)
curl.perform()
progress_plugin.finish()