概要
Python3 で XML ボディを設定して HTTP リクエストする方法を紹介します
標準ライブラリの urllib.request
だけを使用します
環境
- Python 3.7.0
- pipenv 2018.11.14
サンプルコード
- vim app.py
import urllib.request
import urllib.error
if __name__ == '__main__':
requestURL = "https://kaka-request-dumper.herokuapp.com/"
xmlPostBody = """
<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n
<hoge>\n
</hoge>
"""
headers = {
'Content-type': 'application/xml'
}
method = 'POST'
bytesXMLPostBody = xmlPostBody.encode("UTF-8")
req = urllib.request.Request(requestURL, data=bytesXMLPostBody, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as response:
res = response.read().decode("utf-8")
print(res)
except urllib.error.HTTPError as err:
print(err)
ヒアドキュメントを使って XML ボディを生成しています
- python3 app.py
テンプレートを使う
ヒアドキュメントでも問題ないですが管理が辛いので XML データを外出しします
- vim tmpl.xml
<?xml version="1.0" encoding="UTF-8" ?>
<message>
${msg}
</message>
- vim app.py
import urllib.request
import urllib.error
from string import Template
if __name__ == '__main__':
requestURL = "https://kaka-request-dumper.herokuapp.com/"
t = Template(open('./tmpl.xml').read())
xmlPostBody = t.substitute(msg='hello!')
headers = {
'Content-type': 'application/xml'
}
method = 'POST'
bytesXMLPostBody = xmlPostBody.encode("UTF-8")
req = urllib.request.Request(requestURL, data=bytesXMLPostBody, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as response:
res = response.read().decode("utf-8")
print(res)
except urllib.error.HTTPError as err:
print(err)
テンプレート機能を使えば変数を渡すこともできます
こちらのほうがすっきりしている感じがしますが動的に変化する XML などには対応できません
おまけ: dicttoxml を使う方法
- pipenv install dicttoxml
- vim app.py
import urllib.request
import urllib.error
from dicttoxml import dicttoxml
if __name__ == '__main__':
requestURL = "https://kaka-request-dumper.herokuapp.com/"
# xmlPostBody = dicttoxml({'message': 'hello'}, custom_root='messages')
xmlPostBody = dicttoxml({'message': 'hello'}, root=False)
headers = {
'Content-type': 'application/xml'
}
method = 'POST'
req = urllib.request.Request(requestURL, data=xmlPostBody, headers=headers, method=method)
try:
with urllib.request.urlopen(req) as response:
res = response.read().decode("utf-8")
print(res)
except urllib.error.HTTPError as err:
print(err)
ルートのありなしやルートの名前を設定することができます
デフォルトでは type
属性が必ず付与されてしまうので不要な場合は attr_type=False
を設定してください
それ以外にも多くのオプション機能があるので、それらを駆使して自分がほしい XML 情報を生成する必要があります
が、この方法であれば hash をいじればいいので配列要素など簡単に扱うことができます
またバイト文字列として取得されるのでコールする際に encode する必要がなくなります
ちなみに xmltodict もあるのでレスポンスが XML の場合などはこれが使えます
ベーシック認証する方法
import base64
auth = base64.b64encode(('%s:%s' % (username, password)).encode('utf-8'))
headers = {
'Authorization': 'Basic %s' % auth.decode('utf-8')
}
SSL でないページにアクセスする方法
import ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
でコンテキストを作成してコールする際に指定します
urllib.request.urlopen(req, context=ctx)
0 件のコメント:
コメントを投稿