MENU
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
あらゆるモノにHackする、探究者の読み物。
Let's Hack Tech
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
Let's Hack Tech
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
  1. ホーム
  2. プログラミング
  3. 言語別
  4. Python
  5. Re:ゼロから始めるBeatufulSoupによるXMLドキュメント作成【Python】

Re:ゼロから始めるBeatufulSoupによるXMLドキュメント作成【Python】

2023 2/02
Python
2019-08-282023-02-02
Python基礎構文for

WebAPIなんかを使っていると、リクエストをするためにXML文字列をリクエストボディに含める要求方法なんかに出くわします。

Yahooショッピングの注文API関係なんかがそのタイプです。

普段は解析専門のBeautifulSoupですが、ゼロからXMLドキュメントの作成もできるんだぞって事を紹介します。

目次

BeautifulSoupによるXML作成

PythonによるXML作成はメジャーどころで言うと、ElementTreeなんかが紹介されていることも多いですが、実はそれBeautifulSoupでも出来ちゃいます。

パース専門というイメージの強いBeautifulSoupですが、割と万能戦士なんですね。

今回はYahooショッピングの注文APIを例にリクエスト用のXMLを作ってみます。

目的のXMLドキュメント構成

ヤフーショッピングの注文検索APIを今回の題材とします。

要求されるリクエストのXML構造は以下の要件。

パラメータ型説明
/Reqリクエストパラメータ
/Req/Search検索条件指定情報
/Req/Search/Result
(デフォルト : 10)
integer最大取得件数(上限値:2000)
/Req/Search/Start
(デフォルト : 1)
integer取得開始件数
/Req/Search/Sortstring・注文時間で昇順ソート:+order_time(デフォルト)
・注文時間で降順ソート:-order_time
/Req/Search/Condition検索条件
/Req/Search/Condition/
(検索条件キー)
検索条件
/Req/Search/Field
(必須)
string取得情報
/Req/SellerId
(必須)
stringストアアカウント

提示されているサンプルリクエストXML

<Req>
 <Search>
 <Result>50</Result>
 <Start>1</Start>
 <Sort>+order_time</Sort>
 <Condition>
  <OrderId>testseller-10000001</OrderId>
  <DeviceType>1</DeviceType>
  <IsRoyalty>true</IsRoyalty>
  <IsAffiliate>false</IsAffiliate>
  <OrderStatus>2</OrderStatus>
  <StoreStatus>入荷未定</StoreStatus>
  <IsActive>true</IsActive>
  <Seen>true</Seen>
  <IsSplit>false</IsSplit>
  <Suspect>0</Suspect>
  <IsRoyaltyFix>false</IsRoyaltyFix>
  <PayStatus>1</PayStatus>
  <SettleStatus>1011</SettleStatus>
  <PayType>0</PayType>
  <PayMethod>payment_a1</PayMethod>
  <NeedBillSlip>1</NeedBillSlip>
  <NeedDetailedSlip>0</NeedDetailedSlip>
  <NeedReceipt>1</NeedReceipt>
  <BillPrefecture>千葉県</BillPrefecture>
  <BillZipCode>123-4567</BillZipCode>
  <BillPhoneNumber>123-4567-8900</BillPhoneNumber>
  <BillMailAddress>[email protected]</BillMailAddress>
  <ShipStatus>4</ShipStatus>
  <ShipMethod>佐川急便</ShipMethod>
  <ShipRequestDateNo>true</ShipRequestDateNo>
  <ShipCompanyCode>1002</ShipCompanyCode>
  <ShipInvoiceNumber>333-666666-4444</ShipInvoiceNumber>
  <BuyerCommentsFlag>1</BuyerCommentsFlag>
  <ShipPrefecture>千葉県</ShipPrefecture>
  <ShipZipCode>223-4444</ShipZipCode>
  <ShipPhoneNumber>111-2222-3333</ShipPhoneNumber>
  <ItemId>item-a</ItemId>
  <ReleaseDateFrom>21501231</ReleaseDateFrom>
  <ReleaseDateTo>21501231</ReleaseDateTo>
  <GetPointFixDateFrom>20110309</GetPointFixDateFrom>
  <GetPointFixDateTo>20110309</GetPointFixDateTo>
  <UsePointFixDateFrom>20110309</UsePointFixDateFrom>
  <UsePointFixDateTo>20110309</UsePointFixDateTo>
  <IsLogin>true</IsLogin>
 </Condition>
 <Field>OrderId,Version</Field>
 </Search>
 <SellerId>testseller</SellerId>
</Req>

XML階層構造を見極める

XMLって単純にテキスト量がJSONに比べて多くなるので、「うっ・・・」ってなりがちです。

XML全体で見ると、めちゃくちゃ複雑そうに見えますが、上の方で提示されているツリー構造だけみれば、割と単純なもんです。

「Req」というrootの中に「SellerId」「Search」があり、「Search」の中に「Result」「Start」「Sort」「Condition」「Field」の五つの兄弟要素が存在ます。

あまりに長かったので、上で要件を提示してはいませんが、更にCondition直下に条件指定のタグとテキストが兄弟として並ぶ構造です。

BeautifulSoupでXMLを作ってみる

XMLの作成とかはぶっちゃけた話、どのライブラリ作っても大してやることは変わりません(笑)

なら普段からスクレイピングで使い慣れているBeautifulSoupでやってみようと思い、今回の記事に至っています。

使うメソッドは、

  • append()
  • new_tag()

主にこの二つだけです。

XMLの外殻を作成

実際に作成していきます。

from bs4 import BeatifulSoup

# rootタグのみでbs4オブジェクトを生成
# パーサは'lxml-xml'を使います
soup = BeatifulSoup('<Req>', 'lxml-xml')

# 毎回書くのメンドクサイのでメソッド短縮
new = bs.new_tag 
app = bs.Req.append

# ここからどんどんタグを作っていきます
# Req内に「Search」「SellerId」を配置
app(new('Search')), app(new('SellerId'))

# app 作り直し
# append対象がReqだったのでSearchに切り替えます
app = bs.Search.append

# Search内に更に小要素を作る
app(new('Result')), app(new('Start'))
app(new('Sort')), app(new('Field')), app(new('Condition'))

ここまでで要求されているXMLの外殻が完成です。
完成したXMLは以下の状態。

>>>print(bs.prettify())
<?xml version="1.0" encoding="utf-8"?>
<Req>
 <Search>
  <Result/>
  <Start/>
  <Sort/>
  <Field/>
  <Condition/>
 </Search>
 <SellerId/>
</Req>

何かそれっぽくなりましたね。
後は中身をブチ込んでいきます。

タグ内の要素を作成

今回はディフォルトと必須項目を入れていってみます。

Field内にタグは不要なのでリスト型、コンディションはタグが必要なので辞書型で適当にリクエスト作成してXMLにしてみます。

要件の確認はリファレンスから。

Field と Conditionのダミーデータ作成

# Field ダミーデータ作成
# pandasでリファレンスページにアクセス
import pandas as pd
url = 'https://developer.yahoo.co.jp/webapi/shopping/orderList.html'
# Fieldの概要テーブルから項目名をリスト型で根こそぎ取得
Field = pd.read_html(url)[2]['キー名'].tolist()

>>>print(Field)
['OrderId',
 'Version',
 'OriginalOrderId',
 'ParentOrderId',
 'DeviceType',
 'IsActive',
 'IsSeen',
 'IsSplit',
 'IsRoyalty',
 'IsSeller',
 'IsAffiliate',
 'IsRatingB2s',
 'OrderTime',
 'ExistMultiReleaseDate',
 'ReleaseDate',
 'LastUpdateTime',
 'Suspect',
 'OrderStatus',
 'StoreStatus',
 'RoyaltyFixTime',
 'PrintSlipFlag',
 'PrintDeliveryFlag',
 'PrintBillFlag',
 'BuyerCommentsFlag',
 'PayStatus',
 'SettleStatus',
 'PayType',
 'PayMethod',
 'PayMethodName',
 'PayDate',
 'SettleId',
 'UseWallet',
 'NeedBillSlip',
 'NeedDetailedSlip',
 'NeedReceipt',
 'BillFirstName',
 'BillFirstNameKana',
 'BillLastName',
 'BillLastNameKana',
 'BillPrefecture',
 'ShipStatus',
 'ShipMethod',
 'ShipMethodName',
 'ShipRequestDate',
 'ShipRequestTime',
 'ShipNotes',
 'ShipCompanyCode',
 'ReceiveShopCode',
 'ShipInvoiceNumber1',
 'ShipInvoiceNumber2',
 'ShipInvoiceNumberEmptyReason',
 'ShipUrl',
 'ArriveType',
 'ShipDate',
 'NeedGiftWrap',
 'NeedGiftWrapMessage',
 'NeedGiftWrapPaper',
 'ShipFirstName',
 'ShipFirstNameKana',
 'ShipLastName',
 'ShipLastNameKana',
 'ShipPrefecture',
 'PayCharge',
 'ShipCharge',
 'GiftWrapCharge',
 'Discount',
 'UsePoint',
 'TotalPrice',
 'RefundTotalPrice',
 'UsePointFixDate',
 'IsUsePointFix',
 'IsGetPointFixAll',
 'SellerId',
 'IsLogin',
 'PayNo',
 'PayNoIssueDate',
 'SellerType',
 'IsPayManagement',
 'ArrivalDate',
 'TotalMallCouponDiscount',
 'IsReadOnly',
 'IsApplePay',
 'IsFirstClassDrugIncludes',
 'IsFirstClassDrugAgreement']


# ConditionはOrderTime[From][To]の二項目のみ設定
from datetime import datetime
from datetime import timedelta

# 今の時間
now = datetime.now()
# 「今」をフォーマットに従って文字列化
to_default = now.strftime('%Y%m%d%H%M%S')
# 「今」から30日前を計算して、文字列化
from_default = (now - timedelta(30)).strftime('%Y%m%d%H%M%S')

Condition = {
    'OrderTimeTo': to_default,
    'OrderTimeFrom': from_default
}

XMLのタグ内に代入していく

# 外殻作った続きから
bs.SellerId.string = 'test-seller'
bs.Result.string = str(10) # int型だと代入できないので注意
bs.Start.string = str(1) # int型だと代入できないので注意
bs.Sort.string = '+order_time'
bs.Field.string = ','.join(Field)

#コンディションだけはタグ構造なので追加先をappに代入
app = bs.Condition.append
for key in Condition:
    app(new(key))
    bs.find(key).string = Condition[key]

XML完成系

print(bs.prettify())
<?xml version="1.0" encoding="utf-8"?>
<Req>
 <Search>
  <Result>
   10
  </Result>
  <Start>
   1
  </Start>
  <Sort>
   +order_time
  </Sort>
  <Field>
OrderId,Version,OriginalOrderId,ParentOrderId,DeviceType,IsActive,IsSeen,IsSplit,IsRoyalty,IsSeller,IsAffiliate,IsRatingB2s,OrderTime,ExistMultiReleaseDate,ReleaseDate,LastUpdateTime,Suspect,OrderStatus,StoreStatus,RoyaltyFixTime,PrintSlipFlag,PrintDeliveryFlag,PrintBillFlag,BuyerCommentsFlag,PayStatus,SettleStatus,PayType,PayMethod,PayMethodName,PayDate,SettleId,UseWallet,NeedBillSlip,NeedDetailedSlip,NeedReceipt,BillFirstName,BillFirstNameKana,BillLastName,BillLastNameKana,BillPrefecture,ShipStatus,ShipMethod,ShipMethodName,ShipRequestDate,ShipRequestTime,ShipNotes,ShipCompanyCode,ReceiveShopCode,ShipInvoiceNumber1,ShipInvoiceNumber2,ShipInvoiceNumberEmptyReason,ShipUrl,ArriveType,ShipDate,NeedGiftWrap,NeedGiftWrapMessage,NeedGiftWrapPaper,ShipFirstName,ShipFirstNameKana,ShipLastName,ShipLastNameKana,ShipPrefecture,PayCharge,ShipCharge,GiftWrapCharge,Discount,UsePoint,TotalPrice,RefundTotalPrice,UsePointFixDate,IsUsePointFix,IsGetPointFixAll,SellerId,IsLogin,PayNo,PayNoIssueDate,SellerType,IsPayManagement,ArrivalDate,TotalMallCouponDiscount,IsReadOnly,IsApplePay,IsFirstClassDrugIncludes,IsFirstClassDrugAgreement
  </Field>
  <Condition>
   <OrderTimeTo>
    20190828155037
   </OrderTimeTo>
   <OrderTimeFrom>
    20190729155037
   </OrderTimeFrom>
  </Condition>
 </Search>
 <SellerId>
  test-seller
 </SellerId>
</Req>

BeautifulSoupによるXML作成 – 総括

元々パーサのイメージが強いBeautifulSoupですが、十分にXML作成の機能があることは伝わったかと思います。

結構万能なので使い始めると手放せない便利なヤツです。

元々フォーマットが決まっている場合は、わざわざ0から作らなくても、空枠をXMLファイルとして保管しておいて、BeautifulSoupで「テンプレ読み込み」→「代入」→「再出力」なんかでもいいかもしれませんね。

当たり前ですが、XMLの作成だけでなくパース(解析)もできます。以下の記事で紹介してますので、気になる方は覗いてみてください。

あわせて読みたい
BeautifulSoupでXMLをパース(解析)加工する – Python BeautifulSoupはHTMLのパースというイメージがあるかと思いますが、実はXMLの解析にも使えます。基本的にHTMLのパースと要領は同じですが、復習を兼ねて、逆引きリファレンス的にまとめてみます。
10日でおぼえるXML入門教室 第2版
created by Rinker
¥631 (2025/05/09 19:46:50時点 Amazon調べ-詳細)
  • Amazon
  • 楽天市場
  • Yahooショッピング
Python
BeautifulSoup XML
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする コメントをキャンセル

email confirm*

post date*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

シンプル美と機能性を両立させた、国内最高峰のWordPressテーマ『SWELL』
人気記事
  • IQテストいくつか受けてみました
    ネット上で信憑性がありそうなIQテスト、5種類まとめて受けた結果…
  • hayate
    メルカリの商品を世界最速で購入するためだけのアラートツール
  • 【Python】BeautifulSoupの使い方・基本メソッド一覧|スクレイピング
  • Pythonファイルのexe化
    【悲報】PyInstallerさん、300MBのexeファイルを吐き出すようになる
  • Amazon Echo アレクサのコマンドまとめ
    AmazonEchoの使い方とできる事、アレクサへの指示コマンド一覧
最近の投稿
  • 正規表現処理の濁点でハマった話2024-12-12
  • 保護中: 疾風v2更新履歴2024-05-31
  • 【自営・経営者向け・税金も】クレジットカードガチ勢による最強クレカ解説2023-10-23
  • PyQt5 QListWidget の item削除でtextBoxのフォーカスが奪われる2023-03-05
  • WordPressからのメールが届かない時の調査と解決法2023-02-27
目次
目次