Yahoo Search APIとBeautiful Soupを使ったサンプル
ヒゲソリ前にちゃんとプレシェーブローション塗ると、明らかによく剃れることに今更気付いたbonlifeです。数年間、肌にも電気カミソリにも悪いことをしていました…。
id:kadoppeさんのこの記事とPythonネタをいつも読ませていただいているid:aodagさんのこの記事を読んで、Yahoo Search APIを使ったサンプル作りに便乗してみました。というよりid:aodagさんのスクリプトをほぼほぼ流用して、一部改変。(改悪になっていませんように。)
Yahoo Search APIに検索用の文字列を渡して、検索結果を格納した辞書のリストを返すサンプルです。
- yahoo_search_api_sample.py
# -*- coding: utf-8 -*- import urllib import urllib2 from BeautifulSoup import BeautifulStoneSoup class YahooSearchRequest (object): methodurls = dict(web='WebSearchService/V1/webSearch', image='ImageSearchService/V1/imageSearch', video='VideoSearchService/V1/videoSearch', assist='AssistSearchService/V1/assistSearch') baseurl = 'http://api.search.yahoo.co.jp/' def __init__(self, appid, query='', mode='web'): self.url = '%s%s' % (self.baseurl, self.methodurls[mode]) self.params = dict(appid=appid, query=query) self.result = None def addQuery(self, query): self.params['query'] = self.params['query'] + ' ' + query self.result = None return self def __getitem__(self, key): return self.params[key] def __setitem__(self, key, value): self.params[key] = value def search(self, force=False): if self.result is None or force: x = urllib2.urlopen(self.requestUrl) self.result = x.read() return self.result def asBeautifulSoup(self): result = self.search() return BeautifulStoneSoup(result) def asDictList(self): def xmlsoup2dic(soup): dic = {} for k, v in [(tag.name, tag.contents) for tag in soup()]: if len(v) == 1: dic[k] = v[0] else: dic[k] = xmlsoup2dic(soup(str(k))[0]) # dic[k] = [xmlsoup2dic(x) for x in soup(str(k))] return dic b = self.asBeautifulSoup() return [xmlsoup2dic(r) for r in b.findAll('result')] @property def queryString(self): return urllib.urlencode(self.params) @property def requestUrl(self): return '%s?%s' % (self.url, self.queryString) @property def query(self): return self.params['query'] appid = 'hogehoge' # よきにはからってください for x in YahooSearchRequest(appid, mode='web').addQuery('中島みゆき').addQuery('生きて泳げ').addQuery('手嶌葵').asDictList(): print '\n'.join(['%-15s : %s' % (k, v) for k, v in x.iteritems()]) print '-----'
えぇえぇ、asDictListと最後の実行部分しか変えてませんよ。せっかくなので、全要素を取得できた方が良いかな、と思いまして、そのあたりのみ変更してみました。cacheだけがurl、sizeって2つのお子様を持っていて、そのままだと上手く扱えないので、再帰的に処理。XMLの構造があらかじめ分かってる場合はこんなことせずに個別に要素を取り出して、よりフラットな形で取り出した方が扱いやすいかもしれないですね。(上記のスクリプトだとcacheは辞書をそのまま表示してしまいます…。手抜き!)
Beautiful Soupは使い方はシンプルでありながら、結構奥が深そうでした。使いこなせると便利かもかも。XMLよりもちょっとダーティーなHTMLを扱うのに向いてるかもしれないですね。
まぁ、そんなこんなしていて思ったのは、PHPのSimpleXml関数は素人用によく出来てるな、ってことです。あれはすごく楽。楽過ぎです。それっぽいことをやってそうなサンプルを見つけたので、以下にメモしておきます。(試してません。)