27
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PycURLでHTTPリクエストあれこれ

Last updated at Posted at 2016-05-21

pythonでHTTPリクエストを送信するには...requests?
いえいえ、PycURLだってあります。
細かくいろいろあれこれするときはPycURLだよねって人、気持ちわかります :smile:
たまには趣向を変えましょう。

ここでは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

get_example_default.py
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を設定します。

get_example.py
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を設定できます。

set_ua.py
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が取得できます。

set_ua_fakeua.py
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のデータを途中からダウンロードしてみます。

resume.py
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を表示

progress.py
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()
27
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?