Pythonを使用してHTTPリクエストでXMLデータをPOSTする方法を紹介したいと思います。
YahooショッピングAPIやAmazonAPIではデータ送信時にAPI通信時にXML形式のデータをPOSTします。
今回はPython3標準の「urllib」ライブラリを利用してHTTP通信を行います。
※ 「requests」ライブラリを使用することもできます。
ソースコード全文
まずは今回使用するソースコードの全文を紹介します。
import urllib.request
import urllib.error
imort lxml
from bs4 import BeautifulSoup
# 設定値
requestURL = ここのPOSTするURLを記入
xmlPostBody =
<?xml version=\1.0\ encoding=\UTF-8\ ?>\n
ここにXML形式でデータを記入
# POSTリクエスト送信
bytesXMLPostBody = xmlPostBody.encode(UTF-8)
req = urllib.request.Request(url=requestURL, data=bytesXMLPostBody, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as response:
response_body = response.read().decode(utf-8)
soup = BeautifulSoup(response_body, lxml)
print(soup)
except urllib.error.HTTPError as err:
soup = BeautifulSoup(err, lxml)
print(soup)
今回のサンプルでは戻り値がXML形式で返ってくることを想定しております。
なのでBeautifulSoup4を使用してXML形式をタグ解析できるようにしております。
BeautifulSoup4については以下の記事で解説しております。
ヘッダー情報を付与する
ヘッダー情報を渡すためにはPythonの「ディクショナリ」を使用する必要があります。
また送信ファイルはXML形式ですよ!とヘッダー情報に渡すために「Content-type : application/xml;」を指定します。
ソースは以下になります。
headers = {}
headers[Content-type] = application/xml;
print(headers)
各APIに渡すヘッダーの値は「:」コロンで指定します。
XMLデータをバイナリにエンコード
「urllib.request」でデータをPOSTするためには「バイナリコード」に変換した状態で送信する必要があります。
XML形式の文字列をバイナリコードを変換するには「encode()」メソッドを使用します。
以下がソースコードになります。
今回の例では文字コードをUTF-8に変換しております。
xmlPostBody = <?xml version=\1.0\ encoding=\UTF-8\ ?>\n
XMLPostBodyBytes = xmlPostBody.encode(UTF-8)
「urllib.request.Requst」でリクエストオブジェクトの作成
「urllib.request.Request」でオブジェクトを作成します。
上記「URL」、「送信データ」、「Method(GET/POSTなど)」、
「ヘッダー」を指定してオブジェクトを作成します 以下がソース
コードになります。
req = urllib.request.Request(url=<リクエストURL>, data=<送信データ>, headers=headers, method=POST)
「urllib.request.urlopen」でPOSTリクエスト
「urllib.request.urlopen」はURLに直接リクエストを送ることもできますし、
リクエストオブジェクトを渡してURLにリクエストを送ることができます。
今回「urllib.request.urlopen」で先ほど作成したリクエストオブジェクトをPOSTします。
また「with」を使用することで煩わしいリクエスト処理のお作法簡略化させることができます。
以下がソースコードになります。
例では返ってきた値をutf-8形式でデコードし、
BeautifulSoup4でタグ解析を行っています。
req = urllib.request.Request(url=<リクエストURL>, data=<送信データ>, headers=headers, method=POST)
with urllib.request.urlopen(req) as response:
response_body = response.read().decode(utf-8)
soup = BeautifulSoup(response_body, lxml)
print(soup)
「urllib.error.HTTPError」でエラーハンドリング
「urllib.error.HTTPError」と「try~except」を利用することでHTTPリクエスト失敗時の挙動は判別することができます。
404・401・403などパターンに合わせてエラーハンドリングすることも可能です。
以下ソースコードになります。
req = urllib.request.Request(url=<リクエストURL>, data=<送信データ>, headers=headers, method=POST)
try:
with urllib.request.urlopen(req) as response:
response_body = response.read().decode(utf-8)
soup = BeautifulSoup(response_body, lxml)
print(soup)
except urllib.error.HTTPError as err:
soup = BeautifulSoup(err, lxml)
print(soup)
以下にPythonのエラーハンドリングについて解説しておりますので参考にしてみてください。