acokikoy's notes

{"勉強中":"Python","注目":"Shopify","LOVE♡":["ABARTH595","TA-GG9","Ukulele","Movable Type","ガーナ ミルクチョコレート"]} なWebディレクター

RESTful Web APIを扱う時の基本手法のまとめ(cURLコマンド利用)

Web APIの疎通確認するとき、よくつかう操作のあんちょこ、curlコマンド編。

ちょこっとAPIの挙動を味見したい時 curlコマンドやブラウザのネットワークツールが手っ取り早い。はてなブログ など 身近なAPI を例に自分がよく使う操作についてまとめる。

curlコマンドでWeb APIの疎通確認

エンドポイントを叩いて戻り値を確認する時に使うあれこれ。

GET

【基本】エンドポイントを叩く

$ curl 'https://hatenablog.com/oembed?url=https://acokikoy.hatenablog.com/entry/2019/09/22/151213&format=json'

認証付き(-u id:passwd)

$ curl -u {hatena_id}:{api_key} https://blog.hatena.ne.jp/acokikoy/acokikoy.hatenablog.com/atom/entry

POST

フォーム送信
inputタグのvarname=value name を&でつなぐ。スペースなどはURL エンコードすること。

$ curl -d "name=Taro%20Yamada&phone=1234567890" http://www.where.com/guest.cgi

エントリーpost(はてなブログAtomPub 例)

$ curl -X POST --data-binary @entry.xml -u {hatena_id}:{api_key} https://blog.hatena.ne.jp/{hatena_id}/{blog_id}.hatenadiary.com/atom/entry

PUT, DELETE

-X オプションでメソッドを指定する。

$ curl -X PUT --data-binary @entry.xml -u {hatena_id}:{api_key}  https://blog.hatena.ne.jp//{hatena_id}/{blog_id}.hatenadiary.com/atom/entry/26006613442137224$

$ curl -X DELETE -u {hatena_id}:{api_key}  https://blog.hatena.ne.jp/{hatena_id}/{blog_id}.hatenadiary.com/atom/entry/26006613442137224

リクエスト・ヘッダーに情報追加

任意ヘッダー追加 -H, --header <header/@file>

$ curl -H "MyHeader:Hello World" https://acokikoy.hatenablog.com/

レスポンス・ヘッダー情報を見る

# ヘッダーだけ見る
$ curl --head 'https://hatenablog.com/oembed?url=https://acokikoy.hatenablog.com/entry/2019/09/22/151213&format=json'

# ヘッダとデータ両方
$ curl --include 'https://hatenablog.com/oembed?url=https://acokikoy.hatenablog.com/entry/2019/09/22/151213&format=json

--head の代わりに -I
--include の代わりに -iでもOK。

ヘッダ情報としては こんなのが返る

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 29 Sep 2019 07:20:30 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private
Vary: User-Agent, X-Forwarded-Host, X-Device-Type
Content-Security-Policy-Report-Only: block-all-mixed-content; report-uri https://blog.hatena.ne.jp/api/csp_report
P3P: CP="OTI CUR OUR BUS STA"
X-Content-Type-Options: nosniff
X-Dispatch: Hatena::Epic::Web::Global::Oembed#default
X-Frame-Options: DENY
X-Revision: 1c353d7023dcd2b099ff831e84197af3
X-XSS-Protection: 1
X-Runtime: 0.012683
X-Varnish: 190813453
Age: 0
Via: 1.1 varnish-v4
X-Cache: MISS
Accept-Ranges: bytes

JSON/YAML/XML の 整形・フィルタリング処理

取得した JSON/YAML/XMLコマンドラインで整形する方法。

jsonは jq , yamlなら yq, xmlなら xq に渡してやる。きれいに整形表示したり、 json/yaml/xml 間で相互変換してくれる。

JSONを整形・フィルタリング (jq)

  • jq を使うと JSON をきれいに整形したり、指定データだけ取り出したりできる。
  • フィルターの詳しい使い方はココ: jq Manual (development version)
$ curl 'https://hatenablog.com/oembed?url=https://acokikoy.hatenablog.com/entry/2019/09/22/151213&format=json' | jq '.'

# 結果サンプル
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100  2346    0  2346    0     0  10363      0 --:--:-- --:--:-- --:--:-- 10380
{
  "image_url": "https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/0897/4910058270897.jpg?_ex=128x128",
  "title": "形態素解析ツール nagisa で単語分割してWordCloudに出力する(その1)",
  "height": "190",
  "blog_title": "acokikoy's notes",
  "author_name": "acokikoy",
  "version": "1.0",
  "description": "PyConJP 2019 でnagisaという日本語の形態素解析ツールのことを知ったので触ってみる。ただチュートリアルをこなすだけではつまらないので、CMSからAPI経由でウェブサイトのコンテンツを取得してnagisa とWordCloud でテキストマイニングする。今回は その前段。 今回試したこと: nagisa で単語分割、品詞タグ付け、ユーザ辞書を追加する 今回やってないこと: 固有表現抽出モデルの学習 最終的につくりたいもの nagisa とWordCloud でテキストマイニング 参考文献",
  "author_url": "https://blog.hatena.ne.jp/acokikoy/",
  "html": "<iframe src=\"https://hatenablog-parts.com/embed?url=https%3A%2F%2Facokikoy.hatenablog.com%2Fentry%2F2019%2F09%2F22%2F151213\" title=\"形態素解析ツール nagisa で単語分割してWordCloudに出力する(その1) - acokikoy&#39;s notes\" class=\"embed-card embed-blogcard\" scrolling=\"no\" frameborder=\"0\" style=\"display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;\"></iframe>",
  "type": "rich",
  "url": "https://acokikoy.hatenablog.com/entry/2019/09/22/151213",
  "provider_url": "https://hatenablog.com",
  "categories": [
    "Python"
  ],
  "published": "2019-09-22 15:12:13",
  "provider_name": "Hatena Blog",
  "blog_url": "https://acokikoy.hatenablog.com/",
  "width": "100%"
}

YAML, XMLを整形・フィルタリング (yqとxq)

yqとxqは jqのラッパーでそれぞれ YAML, XML ファイルを処理してくれる

# yamlデータをjsonに変換
$ cat sample.yaml | yq '.'

# xmlデータを jsonに変換
$ cat sample.xml | xq '.'

# xmlデータを( jsonに変換後) xmlで整形表示
$ cat sample.xml | xq -x '.'

# xmlデータを jsonに変換後 yamlに変換して整形表示
$ cat sample.xml | xq '.' | yq -y '.'

cURL について少し詳しく

概要

  • curl は データ転送ツール。サーバからデータを取得したり、逆にサーバへデータ転送したりできる。
  • 使えるプロトコルは、DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET , TFTP。
  • ユーザの操作なしに機能するよう作られている。
  • proxy、ユーザー認証、FTPアップロード、HTTPポスト、SSL接続、Cookie、ファイル転送レジューム、Metalinkなどに対応している。

libcurl, PycURL(ライブラリ)

curl (コマンド)

cURLコマンドオプション

Syntax: curl [options] [URL...]

HTTPメソッド制御系

  • -L –location 301 など3xxレスポンスコードが返ってきたときにリダイレクトに従う。Location:ヘッダ の示す先にリダイレクト。
レスポンス・ヘッダ情報
  • -I –head HTTP-header のみ取得する (HTTP/FTP/FILE)
  • -i --include HTTP-header情報付きで データ取得
  • --dump-header と -oオプション HTTP-hederとデータを別ファイルに保存
# ヘッダはファイル保存して、データは画面に表示
$ curl --dump-header headers.txt https://curl.haxx.se 
 
# ヘッダとデータをそれぞれ別ファイルに保存
$ curl --dump-header headers.txt -o body.html https://curl.haxx.se
リクエスト・ヘッダーを追加・変更
  • -H, --header <header/@file> 任意ヘッダー追加 Authorization: MTAuth accessToken=<ACCESS_TOKEN>' ....`
  • -A, --user-agent <name> UserAgent指定
# 任意ヘッダー追加例:
$ curl -H 'MyHeader:Hello World' https://acokikoy.hatenablog.com/

# MT DataAPI でアクセストークンをヘッダーに付加:
$ curl -H 'X-MT-Authorization: MTAuth accessToken=<ACCESS_TOKEN>' (以降 省略)

# ユーザエージェント変更:
$ curl -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0' http://example.jp/
BASIC認証付き
  • -u USER:PASSWORD –user user:password サーバー認証の送信。「:password」部分を省略すると、curl実行時にプロンプトが出てパスワードを聞かれる。

  • 同じことを Authorizationヘッダを使ってもできる。user:password をBase64エンコードして渡す。

$ curl \
    -H "Authorization:Basic $(echo -n USER:PASSWORD | openssl base64)" \
    https://example.com/

echoコマンドの -nオプション は"改行しない"指定。
↓こちらの記事↓を参考にさせていただいた。
curl で Basic 認証(Authorization ヘッダを利用した場合) - ようへいの日々精進XP

  • configfile にuser/passを書いてKオプションで渡してやる方法もある。
# filename.configにuser:passwordを書く
    user="user:password"
    header="-Hで指定してるheaderもここに入れておけば勝手にcurlが送信する"

# curlから読み込む
$ curl -sv -K path/to/filename.config https://url
POSTでよく使う
  • --data-binary @file @file を一切加工しないで送信する。-dオプションと異なり @file内の改行コードが削除されることがないので、Markdown記法など改行が削除されては困るときはこのオプションを使うべし。
  • --data @file -d «string» –data «string» ブラウザから Content-Type application/x-www-form-urlencoded で POST するのと同じ。ASCIIで送る(–data-asciiと同じ)。
  • -F name=@file -F name=content –form name=content Content-Type multipart/form-data でPOSTする

ファイル保存する

画面表示するかわりにファイルに保存する。

  • -O –remote-name 取得元と同じファイル名 で保存
  • -o file –output file 取得元と違うファイル名 で保存
  • 複数URL指定時は、次のように書くとファイル名を個別指定できる。
    $ curl http://{one,two}.site.com -o "file_#1.txt"
    $ curl http://{site,host}.host[1-5].com -o "#1_#2"
  • –create-dirs オプションや –ftp-create-dirs (FTP, SFTP時)を使うと、書き出す時に(存在しない)ディレクトリを生成する。

複数URLをまとめて指定する

  • {..}や[..]を使って複数URLをまとめて指定できる。カッコのネストはできないが、併用はできる。
  • Pythonのスライスみたいなステップ指定ができる。
# {..}や[..]を使って複数URLをまとめて指定できる。
$ curl http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html

# ステップ指定(10飛ばし)
$ curl http://example.com/file[1-100:10].txt

# ステップ指定 (アルファベットでも可能)
$ curl http://example.com/file[a-z:2].txt

ファイルアップロード(FTP)

  • ローカルの指定ファイルを同名でアップロード
    $ curl -T {uploadfile} -u user:passwd ftp://ftp.upload.com/
  • ローカルの指定ファイルを別名でアップロード
    $ curl -T {uploadfile} -u user:passwd ftp://ftp.upload.com/myfile

制御系オプション、デバッグで使うオプション

  • HTTPヘッダ情報取得 も 参照のこと
  • -v –verbose デバッグに役立つより多くの情報を表示する
  • --trace <file> 送受信データを全てトレースダンプする
    • 名に'-' を指定すると、stdoutに出力する
    • 名に'%' を指定すると、stderrに出力する
  • --trace-ascii <file> 送受信データを全てトレースダンプする。16進部分を省略してダンプのASCII部分のみ表示する点が --traceオプションと異なる
    • $ curl 'https://hatenablog.com/oembed?url=https://acokikoy.hatenablog.com/entry/2019/09/22/151213&format=json' --trace-ascii traceascii.txt
    • 名に'-' を指定すると、stdoutに出力する
  • -s –silent 進行状況やエラーメッセージを表示しない
  • -m 10 –max-time 10 操作全体にかかる時間を最大10秒に制限。
  • –limit-rate speed 転送速度の制限

リファレンスへのポインタ