lxmlのobjectifyを試してみたら、すごく便利でビックリした
Javaの試験勉強に集中できないbonlifeです。以下の記事を見て、なんかあったよな、と思ってlxmlのobjectifyを試してみました。
id:tomoemon:20071019:p1 あたりを参考にさせていただきましたよ!
In [1]: from lxml import objectify In [2]: import urllib2 In [3]: url = "http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch?appid=YahooDemo&query=%e6%b2%96%e7%b8%84&results=2" In [4]: root = objectify.parse(urllib2.urlopen(url)).getroot() In [5]: root.countchildren() Out[5]: 2 In [6]: root.getchildren() Out[6]: [<Element {urn:yahoo:jp:srch}Result at 10d1420>, <Element {urn:yahoo:jp:srch}Result at 114ed50>] In [7]: for i in root.Result[0].getchildren(): ....: print "%s\t%s" % (i.tag, i.text) ....: ....: {urn:yahoo:jp:srch}Title 沖縄情報IMA {urn:yahoo:jp:srch}Summary 沖縄の気候、交通、観光、宿泊、遊び等の情報。ホテル、ビーチのオススメランク一覧等。 {urn:yahoo:jp:srch}Url http://www.okinawainfo.net/ {urn:yahoo:jp:srch}ClickUrl http://wrs.search.yahoo.co.jp/l=WS1/R=1/IPC=jp/H=1//SIG=11f2ieaos/EXP=1204973303/*-http%3A//www.okinawainfo.net/ {urn:yahoo:jp:srch}ModificationDate 1204729200 {urn:yahoo:jp:srch}MimeType text/html {urn:yahoo:jp:srch}Cache None In [8]: root.Result.Cache.Size Out[8]: 13812
なんかすごく便利っぽい!ドットでのアクセス最高!ただ、ちょっとイメージと違うところも…。
In [9]: type(root.Result.ModificationDate) Out[9]: <type 'lxml.objectify.IntElement'>
Yahoo!が定義しているXML Schema(こちら)に従うと、コイツは type="xs:string" ってなってるんだけどなぁ…。
明示的にXML Schemaを指定すれば上手く行くかな、と思って試してみたところ…
from lxml import etree, objectify import urllib2 url = "http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch?appid=YahooDemo&query=%e6%b2%96%e7%b8%84&results=2" xsd = "http://api.search.yahoo.co.jp/WebSearchService/V1/WebSearchResponse.xsd" schema = etree.XMLSchema(file=urllib2.urlopen(xsd)) parser = objectify.makeparser(schema=schema) root = objectify.parse(urllib2.urlopen(url),parser=parser).getroot() print type(root.Result.ModificationDate)
の結果が
>yahoo_api_lxml_text.py <type 'lxml.objectify.IntElement'>
ですってよ。ううむ。ちょっとイミフです。でも、YAPIのソース読んでも、types.IntType にしてますね。
class WebSearchResponse(SearchResponse): form = { 'ResultSet': [ {'Result': { 'Title': types.StringType, 'Summary' : types.StringType, 'Url' : types.StringType, 'ClickUrl' : types.StringType, 'MimeType' : types.StringType, 'ModificationDate': types.IntType, 'Cache' : types.StringType, } } ] }
そもそもこの項目の意味は「ページが最後に修正された日付です。UNIXタイムスタンプフォーマットです。」ってことらしいので、types.IntType で正解なのかな。XML Schema が間違ってる?
謎が謎を呼ぶので、今日はこのあたりにしておきます。言いたいことは2点。
- 外部モジュールに依存して楽しても良い気がする (lxml万歳!)
- XML Schemaまわりが謎過ぎる
ということで、lxmlでXML Schemaあたりをゴニョゴニョするのに詳しい人、ヘルプミーです!