Google App EngineでのXMLを使った処理
どうやっているか
XMLから情報を得たいときには
- XML文字列そのものを取得
- その文字列をパースする(DOMを取得)
- DOMから指定したタグの情報を取得する
という流れになると思うんですが、Google App EngineでXMLのパースをどうやってやればいいかちょっと悩んだので書いておきます。
まず1.はgoogle.appengine.apiのurlfetchを使えばOKです。
問題は2と3なんですが、今回はxml.domのminidomを使ってみました。
本当はElementTreeというPythonのXMLパーサライブラリを使うと
もっと柔軟にかつ楽にXMLを処理できるのですが、Google App Engineではデフォルトで使えないのでやめました。*1
minidomではparseString()メソッドでXMLをパースできます。
そしてそのDOMのgetElementsByTagName("タグ名")でタグ名のタグのNode配列が取得できます。
xml = urlfetch.fetch(url).content
dom = minidom.parseString(xml)
nodes = dom.getElementsByTagName("tag")
それぞれのNodeからタグ内の文字を取得するときは、
for node in nodes: print node.childNodes[0].data
のようにすると取得できます。
ちなみに上のニコニコ動画のタグを取得するサンプルはGoogle App Engineを使って書きました。
http://voidy21.appspot.com/nicotag_example/index.html
ニコニコ動画のXML情報をJSON形式で返して、jQueryを使って表示しました。
サーバ(python)のソース
# -*- coding: utf-8 -*- import wsgiref.handlers import cgi from xml.dom import minidom from django.utils import simplejson from google.appengine.ext import webapp from google.appengine.api import urlfetch class GetNicoTags(webapp.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'application/json' self.response.headers['charset'] = 'UTF-8' callback = cgi.escape(self.request.get('callback')) video_id = cgi.escape(self.request.get('video_id')) url = 'http://www.nicovideo.jp/api/getthumbinfo/%s' % (video_id) xml = urlfetch.fetch(url).content dom = minidom.parseString(xml) tags = dom.getElementsByTagName("tag") nicotags = {"tags":[]} append_nico = nicotags["tags"].append for tag in tags: append_nico({"tag":tag.childNodes[0].data}) self.response.out.write("%s(%s)" % (callback, simplejson.dumps(nicotags, ensure_ascii=False))) application = webapp.WSGIApplication([ ('/nicotag', GetNicoTags), ], debug=False) def main(): wsgiref.handlers.CGIHandler().run(application) if __name__ == '__main__': main()
*1:使いたいときは、elementtreeディレクトリを作ってPyWrapperのSimpleXMLTreeBuilder.pyとElementTree.pyを落としてきて、__init__.pyという名前の空のファイルを作成しておく。そして[http://mattn.kaoriya.net/software/lang/python/20080424212547.htm:title]を参考にしてElementTree.pyを書き換える。