PycURLを使用してPythonでcURLを使用する

このチュートリアルでは、PythonのcURLライブラリへのインターフェースであるPycURLの使い方を学びます。

cURLは、サーバーとの間でデータを転送したり、さまざまな種類のデータ要求を行うために使用されるツールです。

PycURLはREST APIをテストしたり、ファイルをダウンロードしたりするのに最適です。

開発者の中にはAPIのテストにPostmanを使うことを好む人もいますが、PycURLはFILE、FTPS、HTTPS、IMAP、POP3、SMTP、SCP、SMBなどの複数のプロトコルをサポートしているので、APIのテストに適した別のオプションと言えます。

さらに、PycURLは、多くの同時接続、高速接続、および信頼性の高い接続が必要な場合に便利です。

前述のとおり、PycURLはPythonのlibcURLライブラリへのインタフェースであり、したがってPycURLはlibcURLのすべての機能を継承しています。

PycURLは非常に高速で(HTTPリクエスト用のPythonライブラリであるRequestsよりもはるかに高速であることが知られています)、マルチプロトコルをサポートしており、ネットワーク操作をサポートするためのソケットも含まれています。

前提条件

このチュートリアルを進める前に、いくつかの前提条件があることに注意してください。

Pythonの構文の基本的な理解、および/または、他の言語での少なくとも初級レベルのプログラミング経験が必要です。

さらに、プロトコルとその型、クライアントサーバーモードの通信のような一般的なネットワークの概念についてよく理解している必要があります。

これらの概念に精通していることは、PycURLライブラリを理解するために必要不可欠です。

インストール

PycURLのインストール手順は、すべてのオペレーティングシステムでかなりシンプルで簡単です。

PycURLを使用するためには、システムにlibcURLをインストールする必要があるだけです。

Mac/Linux OS

Mac OSとLinuxの場合、PycURLのインストールは依存関係がなく、libcURLがデフォルトでインストールされているため、最も簡単な方法です。

ターミナルで以下のコマンドを実行するだけで、インストールが完了します。

pipによるインストール
$ pip install pycurl


Easy_install によるインストール
$ easy_install pycurl


Windows OS

しかし、Windowsの場合、PyCURLをプログラムで使用する前にインストールする必要がある依存関係がいくつかあります。

Pythonの公式ディストリビューション(公式サイト https://www.python.org からPythonのバージョンをダウンロードしたもの)とpipを使用している場合は、コマンドラインで以下のコマンドを実行するだけでインストールは完了します。

$ pip install pycurl


pipを使用していない場合は、PycURL WindowsでEXEとMSIのインストーラが利用できます。

他のアプリケーションと同様に、そこから直接ダウンロードし、インストールすることができます。

基本的なコード例

このセクションでは、インターフェイスのさまざまな機能を示すPycURLのコーディング例をいくつか取り上げます。

導入のセクションで述べたように、PycURLは多くのプロトコルをサポートし、多くの洗練された機能を備えています。

ただし、この例ではHTTPプロトコルを使用して、HTTPの最も一般的に使用されるメソッドを使用してREST APIをテストする予定です。

GET、POST、PUT、DELETE、およびその他のいくつかの例もあります。

Python 3でそれらを宣言するための構文を書き、またそれらが何を行うかを説明します。

では、始めましょう

例 1:HTTP GET 要求を送信する

PycURLの簡単なネットワーク操作は、指定されたサーバーからそのURLを使用して情報を取得することです。

これは、ネットワークリソースを「取得」するために使用されるため、GETリクエストと呼ばれます。

PycURLを使用して単純なGETリクエストを実行するには、BytesIOモジュールをインポートして、そのオブジェクトを作成します。

CURLオブジェクトは、URL上でデータやファイルを転送するために作成されます。

目的の URL は setopt() 関数を使用して設定します。

この関数は setopt(option, value) として使用されます。

optionパラメータは、URLWRITEDATAなど、どのオプションを設定するかを指定し、value` パラメータはその特定のオプションに与えられた値を指定する。

設定された URL から取得されたデータは、BytesIO オブジェクトにバイトの形式で書き込まれます。

そのバイトは getvalue() 関数を使って BytesIO オブジェクトから読み込まれ、その後デコードされてコンソールに HTML が出力されます。

以下は、その方法の例です。

import pycurl
from io import BytesIO


b_obj = BytesIO() 
crl = pycurl.Curl()


# Set URL value
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')


# Write bytes that are utf-8 encoded
crl.setopt(crl.WRITEDATA, b_obj)


# Perform a file transfer 
crl.perform()


# End curl session
crl.close()


# Get the content stored in the BytesIO object (in byte characters) 
get_body = b_obj.getvalue()


# Decode the bytes stored in get_body to HTML and print the result 
print('Output of GET request:
%s' % get_body.decode('utf8'))


出力

Output of GET request:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"

<html
<head
<meta content="IE=Edge" http-equiv="X-UA-Compatible"/
<meta content="width=device-width, initial-scale=1" name="viewport"/
<meta content="text/html; charset = utf-8" http-equiv="Content-Type"/
<meta content="index,nofollow" name="robots"/
<titleBeginnersGuide - Python Wiki</title
<script src="/wiki/common/js/common.js" type="text/javascript"</script
<script type="text/javascript"
<!--
var search_hint = "Search";
//--
</script
.
.
.


例2:GETレスポンスヘッダを調べる

PycURLの助けを借りて、Webサイトのレスポンスヘッダを取得することもできます。

レスポンスヘッダを調べる理由はいくつかありますが、たとえば、レスポンスとともに送信されたエンコードが何であるか、またそれがサーバーから提供されたエンコードに従っているかどうかを調べることができます。

この例では、レスポンスヘッダを調べて、さまざまな属性名とそれに対応する値を確認します。

レスポンスヘッダを調べるには、まずそれを抽出する必要があります。

そのためには HEADERFUNCTION オプションを使用し、自分で定義した関数 (この例では display_header()) でそれを表示させます。

HEADERFUNCTIONはレスポンスヘッダをdisplay_header()` 関数に送り、そこで適切にフォーマットされます。

レスポンスヘッダは指定された標準に従ってデコードされ、対応する名前と値に分割されます。

名前と値の間の空白は取り除かれ、小文字に変換される。

レスポンスヘッダはBytesIOオブジェクトに書き込まれ、リクエスタに転送され、最終的に適切なフォーマットで表示されます。

from io import BytesIO
import pycurl


headers = {}


def display_header(header_line):
    header_line = header_line.decode('iso-8859-1')


# Ignore all lines without a colon
    if ':' not in header_line:
        return


# Break the header line into header name and value
    h_name, h_value = header_line.split(':', 1)


# Remove whitespace that may be present
    h_name = h_name.strip()
    h_value = h_value.strip()
    h_name = h_name.lower() # Convert header names to lowercase
    headers[h_name] = h_value # Header name and value.


def main():
    print('**Using PycURL to get Twitter Headers**')
    b_obj = BytesIO()
    crl = pycurl.Curl()
    crl.setopt(crl.URL, 'https://twitter.com')
    crl.setopt(crl.HEADERFUNCTION, display_header)
    crl.setopt(crl.WRITEDATA, b_obj)
    crl.perform()
    print('Header values:-')
    print(headers)
    print('-' * 20)

main()


出力する。

**Using PycURL to get Twitter Headers**
Header values:-
{'cache-control': 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0', 'content-length': '303055', 'content-type': 'text/html;charset=utf-8', 'date': 'Wed, 23 Oct 2019 13:54:11 GMT', 'expires': 'Tue, 31 Mar 1981 05:00:00 GMT', 'last-modified': 'Wed, 23 Oct 2019 13:54:11 GMT', 'pragma': 'no-cache', 'server': 'tsa_a', 'set-cookie': 'ct0=ec07cd52736f70d5f481369c1d762d56; Max-Age=21600; Expires=Wed, 23 Oct 2019 19:54:11 GMT; Path=/; Domain=.twitter.com; Secure', 'status': '200 OK', 'strict-transport-security': 'max-age=631138519', 'x-connection-hash': 'ae7a9e8961269f00e5bde67a209e515f', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'x-response-time': '26', 'x-transaction': '00fc9f4a008dc512', 'x-twitter-response-tags': 'BouncerCompliant', 'x-ua-compatible': 'IE=edge,chrome=1', 'x-xss-protection': '0'}
--------------------


同じ名前のヘッダーが複数ある場合、最後のヘッダーの値だけが保存されます。

複数の値を持つヘッダーにすべての値を格納するには、次のようなコードを使用します。

if h_name in headers:
    if isinstance(headers[h_name], list):
        headers[name].append(h_value)
    else:
        headers[h_name] = [headers[h_name], h_value]
else:
    headers[h_name] = h_value


例3:HTTP POSTでフォームデータを送信する

POSTリクエストとは、HTTPリクエストのボディにデータを囲んでWebサーバーに送信するものです。

ファイルのアップロードやフォームの送信は、基本的にPOSTリクエストを指定のサーバーに送信していることになります。

POSTリクエストは、PycURLを使用して、まず setopt 関数でフォームデータを送信するURLを設定することで実行できます。

送信されるデータは、まず(キーと値のペアで)辞書の形式で保存され、次に urllib.parse モジュールにある urlencode 関数を使用して URL エンコードされます。

POSTFIELDSオプションを使用すると、HTTP リクエストメソッドを自動的に POST に設定し、pf` データも扱えるようになります。

from urllib.parse import urlencode
import pycurl


crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
data = {'field': 'value'}
pf = urlencode(data)


# Sets request method to POST,
# Content-Type header to application/x-www-form-urlencoded
# and data to send in request body.
crl.setopt(crl.POSTFIELDS, pf)
crl.perform()
crl.close()


注意: 別のリクエストメソッドを指定したい場合は、 CUSTOMREQUEST オプションを使用することができます。

crl.CUSTOMREQUEST` に続く空の逆カンマに、好きなリクエストメソッドの名前を書けばよい。

crl.setopt(crl.CUSTOMREQUEST, '')


例 4:マルチパート POST を使用してファイルをアップロードする

PycURLを使用してHTMLフォームにファイルをアップロードする方法を再現するには、いくつかの方法があります。

    1. POSTリクエストで送信するデータがシステム上のファイルにある場合、まずデータを送信したいURLを設定する必要があります。次に、リクエストメソッドを HTTPPOST に指定し、fileupload オプションを使用して目的のファイルのコンテンツをアップロードします。
import pycurl


crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')


crl.setopt(crl.HTTPPOST, [
    ('fileupload', (
        # Upload the contents of the file
        crl.FORM_FILE, './my-resume.doc',
    )),
])
crl.perform()
crl.close()


注意: もし、ファイルの名前やコンテントタイプを変更したい場合は、上記のコードを少し修正することで可能です。

crl.setopt(crl.HTTPPOST, [
    ('fileupload', (
        # Upload the contents of this file
        crl.FORM_FILE, './my-resume.doc',
        # Specify a file name of your choice
        crl.FORM_FILENAME, 'updated-resume.doc',
        # Specify a different content type of upload
        crl.FORM_CONTENTTYPE, 'application/msword',
    )),
])


  1. メモリ上にあるファイルデータの場合、POSTリクエストの実装で変わるのは、FORM_FILEの代わりに FORM_BUFFERFORM_BUFFERPTRを指定することだけです。
import pycurl


crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')


crl.setopt(crl.HTTPPOST, [
    ('fileupload', (
        crl.FORM_BUFFER, 'contact-info.txt',
        crl.FORM_BUFFERPTR, 'You can reach me at billy@example.com',
    )),
])


crl.perform()
crl.close()


例5:HTTP PUTでファイルをアップロードする

PUTリクエストは、リクエストのボディでファイルをアップロードするために使用できるという事実を除いて、POSTリクエストと性質が似ています。

作成または上書きしたいオブジェクトの URL がわかっている場合に、PUT リクエストを使用します。

基本的にPUTは、対象のURLに現在存在するものを何か別のものに置き換えます。

アップロードしたいデータが物理的なファイルにある場合、まずターゲットURLを設定する必要があり、次にファイルをアップロードしてそれを開きます。

cURLオブジェクトがそのファイルを使用している間、ファイルを開いておくことが重要です。

次に READDATA を使ってファイルからデータを読み取ります。

最後に、perform関数を用いてファイルの転送(アップロード)を行い、cURLのセッションを終了します。

最後に、CURL オブジェクトのために最初に開かれたファイルが閉じられます。

import pycurl


crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')


dat_file = open('data.txt')


crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, dat_file)


crl.perform()
crl.close()
dat_file.close()


ファイルのデータがバッファに格納されている場合、PycURLの実装は物理ファイルに格納されたデータのアップロードとほぼ同じですが、若干の変更が加えられています。

BytesIOオブジェクトは、指定された規格を使用してデータをエンコードします。

これは、READDATAがIO的なオブジェクトを必要とし、エンコードされたデータがPython 3に不可欠であるためです。

エンコードされたデータはバッファに保存され、そのバッファが読み込まれます。

データのアップロードが行われ、アップロードが完了すると、cURLのセッションが終了します。

import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')


data = '{"person":{"name":"billy","email":"billy@example.com"}}'
buffer = BytesIO(data.encode('utf-8'))


crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, buffer)


crl.perform()
crl.close()


例 6: HTTP DELETE リクエストを送信する

もうひとつの重要でよく使われる HTTP メソッドに DELETE があります。

DELETE メソッドは、サーバがターゲット URL で特定されるリソースを削除するよう要求します。

これは、以下のコードにあるように CUSTOMREQUEST 関数を用いて実装することができます。

import pycurl


crl = pycurl.Curl()
crl.setopt(crl.URL, "http://api.example.com/user/148951")
crl.setopt(crl.CUSTOMREQUEST, "DELETE")
crl.perform()
crl.close()


例 7:ファイルへの書き込み

PycURLは、応答をファイルに保存するためにも使用できます。

ファイルを開くには open 関数を使用し、応答はファイルオブジェクトとして返されます。

open関数は次のような形式です。

open(file, mode) という形式である。

fileパラメータは開くファイルのパスと名前を表し、modeはファイルを開くときのモードを表します。

この例では、レスポンスのエンコードとデコードを避けるために、ファイルをバイナリモード (すなわちwb`) で開くことが重要である。

import pycurl


file = open('pycurl.md','wb')


crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')
crl.setopt(crl.WRITEDATA, file)
crl.perform()
crl.close()


結論

このチュートリアルでは、PythonのPycURLインターフェイスについて学びました。

まず、PycURL の一般的な機能の一部と、Python の libcURL ライブラリとの関連について説明しました。

次に、さまざまなオペレーティングシステムに対する PycURL のインストール手順を確認しました。

最後に、HTTP GET、POST、PUT、DELETEメソッドなど、PycURLが提供するさまざまな機能を実証するPycURLの一般的な例をいくつか見ていきました。

このチュートリアルに従った後は、Pythonプログラム内でURLによって特定されるオブジェクトを簡単に取得できるようになるはずです。

タイトルとURLをコピーしました