Python3 – WebAPI

概要

PythonでWebAPIによってデータをリクエストして取得する方法をまとめる。ここでは郵便番号配信サービスのzipcloudのAPIを利用する。

流れは以下の通り。

  1. 準備
    1. urllib.requestライブラリーのインポート
    2. APIエンドポイントURLのセット
    3. パラメーターのセット
    4. パラメーターのエンコード
  2. リクエストとレスポンス
    1. Requestオブジェクトの生成
    2. リクエスト実行とResponseオブジェクトの取得
  3. レスポンスオブジェクトのデコード

API仕様

zipcloudサイトの郵便番号検索APIの内容をまとめると以下の通り。

  • リクエストURL:https://zipcloud.ibsnet.co.jp/api/search
  • リクエストパラメーター
    • zipcode~必須~郵便番号(ハイフンなし7桁の数字)
    • callback~オプション~JSONPとして出力する際のコールバック関数名
    • limit~オプション~同一の郵便番号で複数のデータが存在する場合に返される上限件数(デフォルト20)
    • urlパターンの例:https://zipcloud.ibsnet.co.jp/api/search?zipcode=1330051

コード

最初に実行コードの全体を示す。

コード説明

準備

urllib.requestライブラリーのインポート

HTTPリクエストに必要なurllib.requestライブラリーをインポートする。

APIエンドポイントURLのセット

ここではzipcloudのAPIエンドポイントのURLを変数urlにセットする。

リクエストパラメーターのセット

リクエストパラメーターを辞書でセット。ここでは仕様に従ってzipcode'1130051'を与えている。

パラメーターのエンコード

リクエストに備えて、パラメーター文字列をバイト列にエンコード。ここでは一般的なutf-8を指定しているが、郵便番号は半角数字なのでasciishift_jisでも同じ結果となる。その形式は

urllib.parse.urlencode(パラメーター辞書).encode('文字コード')

リクエストとレスポンス

Requestオブジェクトの生成

ベースのURLとエンコードされたパラメーターを与えてRequestオブジェクトを生成する。

urllib.request.Request(URL文字列, data=エンコード後のパラメーター)

リクエスト実行とResponseオブジェクト取得

リクエストはRequestオブジェクトを引数としてurlopenメソッドを実行。戻り値は結果のResponseオブジェクト。

Responseオブジェクトのデコード

取得したままのResponseオブジェクトをそのまま表示しても、クラスの文字列表現となるだけ。

そこで、文字コードを指定してデコードしてやる。ここではutf-8を指定している。

response.read().decode(文字コード)

結果は文字コードで指定されたエンコード方式でデコードされ、レスポンスの文字列が得られる。

zipcloudのレスポンスはJSON形式でインデント整形された文字列となるが、あくまで文字列であり、要素を指定した値の取出しはできない。

JSON文字列の取り扱い

準備

JSON形式の文字列を辞書として読み込んだり、整形表示をしてみる(PythonでのJSONの取り扱い)。

まず、JSONを扱うにはjsonライブラリーが必要。

辞書への展開

JSON形式の文字列をPythonの辞書として取り込む。

json.loads(JSON形式の文字列)

レスポンス内容の取出し

これはzipcloudの仕様になるが、レスポンスのJSONデータのレスポンス部分は入れ子の内側('response'キーに対応)にあるので、これを取り出す。

同じ郵便番号に複数の住所が存在する場合もあるが、ここでは最初の1つだけ取り出している。

JSON形式での整形出力

辞書の内容を再度整形して文字列化する。

json.dumps(辞書, indent=桁数)

ただし、このままではマルチバイト文字が16進にエスケープされてしまう。

エスケープの抑制

json.dumpsでエスケープを抑制することで、もとの文字コードに基づいて処理される。エスケープを抑制するためには引数でensure_ascii=Falseをセットする。

 

ISO-20220-JP/EUC-JP/Shift-JISなど

概要

JIS X 0208の符号化方式として以下の3つを整理する。

  • ISO-2022-JP~JISコード
  • EUC-JP
  • Shift_JIS

ISO-2022-JP

JIS X 0208の符号化

区点番号を16進4桁とし、0x2020を加えて2バイトのバイト列を得る。以下、いくつかの例。

全角文字 区点(10進) 区点(16進) 符号化後
4/2 0x0402 24 22
4/21 0x0415 24 35
16/1 0x1001 30 21
28/79 0x1C4F 3C 6F

エスケープシーケンス

ASCII文字の解釈で始め、ASCIIにエスケープした状態で終了。

以下は文字集合、バッファーとそれに切り替えるためのエスケープシーケンス。

文字集合 バッファー 16進 文字表記
ASCII G0 1B 28 42 ESC ( B
JIS X 0201 G0 1B 28 4A ESC ( J
JIS X 0208 G0 1B 24 42 ESC $ B

以下は、「ABアイあい」という文字列のISO-2022-JPによるエンコーディングの結果。

区/点 バイト表現 変換・制御 バイト列
A 41 41
B 42 42
C 43 43
JIS X 0201 1B 28 4A
B1 B1
B2 B2
JIS X 0208 1B 24 42
4/4 0404 +0x2020 24 24
4/5 0405 +0x2020 24 25
ASCII 1B 28 42

EUC-JP

EUC-JPでは以下のようにエンコードする。

  • ASCIIをGL領域、JIS X 0208をGR領域で扱う
  • ASCIIは最上位ビットが0でそのままのビットパターン
  • JIS X 0208は区点コードに0xA0A0を加えた値となる
  • 半角カタカナ(JIS X 0201)はSS2 (Single Sift 2, 0x8E)で1文字ごとにエスケープ
  • 補助漢字(JIS X 212)はSS3 (Single Shift 3, 0x8F)で1文字ごとにエスケープ

なお、区の最大値は84(0x54)、点の最大値は95(0x5F)なので、0xA0を加えてもオーバーフローしない。

全角文字 区点(10進) 区点(16進) 符号化後
4/2 0x0402 A4 A2
4/21 0x0415 A4 B5
16/1 0x1001 B0 A1
28/79 0x1C4F BC EF

エスケープ

JIS X 0201とJIS X 0212の文字の前、1文字ごとにそれぞれエスケープシーケンス0x8E0x8Fを置く。ASCIIとJIS X 0208は同居しているので、エスケープシーケンスは必要ない。

以下は文字集合、バッファーとそれに切り替えるためのエスケープシーケンス。ただしJIS X 0201とJIS X 0212へのエスケープの実装は任意。

文字集合 バッファー 16進 文字表記
ASCII G0
JIS X 0208 G1
JIS X 0201 G2 8E SS2
JIS X 0212 G3 8F SS3

以下は、「ABアイあい」という文字列のEUC-JPによるエンコーディングの結果。

区/点 バイト表現 変換・制御 バイト列
A 41 41
B 42 42
C 43 43
JIS X 0201 8E
B1 B1
JIS X 0201 8F
B2 B2
JIS X 0208 1B 24 42
4/4 0404 +0xA0A0 A4 A4
4/5 0405 +0xA0A0 A4 A5

Shift_JIS

概要

英数字・半角カナ・漢字をエスケープシーケンスなしで1~2バイトの符号空間で表現する。

  • 半角英数字と半角カタカナは1バイト
  • 日本語の全角文字は2バイト

Shift_JISのシフトは、文字集合を符号空間の空き領域にシフトさせて詰め込んでいることから。

特徴など

  • エスケープシーケンス不要
  • 符号化後の容量が他と比べて小さい
  • JIS X 0208の区点からの変換式が煩雑
  • 2バイト目にASCIIコードと同じ符号が現れるため、文字区切りの判定に制約
    • 一部の文字に0x5Cが現れ、これがASCIIのバックスラッシュ/¥記号に相当するため、ソースコードの処理などで不都合が生じる、など

 

JIS X 0208

概要

日本語表記のための漢字・図形の符号化文字集合(の規格)。7ビット及び8ビットの2バイトで表現。「7ビット及び8ビットの2バイト情報交換用符号化漢字集合」(7-bit and 8-bit double byte coded KANJI sets for information interchange)。

図形文字は94×94=8834の区点に非漢字524字、第一水準漢字2965字、第二水準漢字3390字の6879字が定義されている。

コード表

構造

JIS X 0208は区(row)と点(cell)の交点に文字を定義する。各区に対して80の点が定義され、1つの文字は「区/点」で表される(コードポイント)。

たとえば1区のコード表は以下のとおり。

+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
1 0 ´ ¨
16 _
32
48 ± ×
64 ÷ °
80 §

 

割当て

1区~8区 記号・英数・かな
16区~47区 第1水準漢字
48区~84区 第2水準漢字

1区~8区の内訳は以下のようになっている。

1~2区 記号
3区 数字、アルファベット
4区 平仮名
5区 片仮名
6区 ギリシャ文字
7区 ロシア文字
8区 罫線文字

JIS X 0208の一部を例示すると以下のとおり。「あ」は4区2点、「愛」は16区6点となる。

区\点 1 2 3 4 5 6 7 8 9 10
2/1 2/2 2/3 2/4 2/5 2/6 2/7 2/8 2/9 2/A
1 2/1
2 2/2
3 2/3
4 2/4
5 2/5
6 2/6 Α Β Γ Δ Ε Ζ Η Θ Ι Κ
7 2/7 А Б В Г Д Е Ё Ж З И
8 2/8
9 2/9
: : : : : : : : : : : :
15 2/F
16 3/0
17 3/1
18 3/2
: : : : : : : : : : : :

参考~JIS X 0208の文字コード

区点の仕組み

区/点と列/行

JIS-X0208は2バイトで文字を表現する。2バイトのうち1バイトを「区」(row)とし、第2バイトを「点」(cell)とする。

1バイトを上位ビットと下位ビットに分け、上位ビットを「列」、下位ビットを「行」とする。

1バイトが7ビットの場合、000|0000~111|1111の128パターンが表現可能だが、このうち34パターンが1バイト文字として先取りされる。このため、区及び点を表現できる1バイトのパターン数は94となる。

列/行

2バイト文字の1バイトのパターンの表現方法。1バイトを上位3 or 4ビット(列)と下位4ビット(行)に分け、それぞれの10進数表記を'/'で区切って「列番号/行番号」とする。たとえば7ビットの場合、011|1011は3/11(3列11行)となる。

1バイトが7ビットの場合、000|0000~111|1111すなわち0/0~7/15で、その数8×16=128が全体のパターン数となる。但し後述のように、このうち34パターンが1バイト文字に先取りされるため、2バイト文字として使用可能なのは128−34→94パターンとなる。

1バイト文字

1バイト文字には以下の34文字(制御文字とSPACE)が予約される。

制御文字

0列(0/0~0/15)と1列(1/0~1/15)の32個の領域には制御文字を配置する(CL領域)。

SPACE

2/0にはSPACE(空白)を配置する。

DELETE

7/15にはDELETE(抹消)を配置する。

7ビット2バイトの場合

上位7ビットを区、下位8ビットの1バイトを点とする。

  • CL領域(0/0~1/15)の制御文字
  • 2/0のSPACE
  • 7/15のDELETE
  • GL領域(2/1~7/14)の図形文字
    →2バイトで94×94区点

8ビット2バイトの場合

8ビット2バイトの場合、7ビット2バイトに対して、1バイト目の最上位ビットが加わる。

最上位ビットが0の場合、7ビット2バイトと同じで、区や点のパターンは0/0~7/15の128パターン。

  • CL領域(0/0~1/15)の制御文字
  • 2/0のSPACE
  • 7/15のDELETE
  • GL領域(2/1~7/14)の図形文字
    →2バイトで94×94区点

一方、1バイト目の最上位ビットが1の場合は、区や点のパターン数は8/0~15/15でパターンを以下のように割り当てる。

  • CR領域(8/0~9/15)の制御文字
  • 10/0、10/15は不使用
  • GR領域(10/1~15/14)の図形文字
    →2バイトで94×94区点

GR領域の考え方はGL領域と同じで、94×94の区点で8836個の文字を配置可能。

 

 

 

JIS X 0201

概要

7ビット及び8ビットの情報交換用符号化文字集合。ラテン文字用図形文字集合と片仮名用図形文字集合のふたつの文字集合からなっている。半角英数、半角カナ。俗称ANKコード (Alphabet Numeric Katakana) 。

このJIS X 0201はJIS X 0208と併せてShift_JISやEUC-JPで用いられる。JIS X 0201の殆どの文字はJIS X 0208の一部と重複するので、半角で表示されることが多い。

文字集合

ラテン文字用図形文字集合

8ビットの場合、0010|0001~0111|1110(0x21~0x7E)の94文字に図形文字を割り当てている。先頭ビットが0で、7ビットでそれ以降のパターンは変わらない。

ASCIIとほぼ同じ並びだが、以下の2つの文字の表現がASCIIと異なる。

  • 5C:\¥
  • 7E:~→ ¯
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
20 ! # $ % & ( ) * * , . /
30 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
40 @ A B C D E F G H I J K L M N O
50 P Q R S T U V W X Y Z [ ¥ ] ^ _
60 ` a b c d e f g h i j k l m n o
70 p q r s t u v w x y z { | } ¯

 

片仮名用図形文字集合

8ビットの1010|0001~1111|1110(0xA1~0xFE)の94文字に図形文字を割り当てている。7ビットの場合は先頭ビットの1を無視する。

半角カタカナや記号として表示される。

+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F
A0
B0
C0
D0
E0
F0

 

7ビット/8ビット

8ビットの場合は、0x21~0x7Eにラテン文字、0xA1~0xFEに片仮名文字を割り当てる。

7ビットの場合は、SIHT-OUT  (SO, 0x0E)、SHIFT-OUT (SO, 0x0F)でラテン文字とカタカナ文字を切り替える。SO以降は片仮名、SI以降はラテン文字となる。