pythonでYahoo BOSS APIを使うサンプルコード

Yahoo BOSS APIを使ったpythonのサンプルプログラムです。実はHTTPリクエストで長らく失敗していたのですが、'Accept-encoding'を設定することで、解決できました。この件についてはHatena::Questionやmixiなどを通じ、沢山のアドバイスを頂きました。本当に感謝しております。

ソースコードは以下の通りです。こちらは、公式のBOSS Frameworkよりもずっとシンプルなのが特徴です。

#!/virtual/taos/bin/python
#!-*- coding:utf-8 -*-

import sys
import site

import os
import re
import codecs
import cgi;
import cgitb; cgitb.enable()
import logging
import datetime
from urllib import urlencode
from urllib import quote_plus
import urllib2
import simplejson

#BOSSのAppIDはconfig.json内に忍ばせてます(BOSS Framework参照)
CONFIG = simplejson.load(open("config.json", "r"))
SEARCH_API_URL = CONFIG["uri"] + "%s/v%d/%s?start=%d&count=%d&lang=%s&region=%s" + "&appid=" + CONFIG["appid"]

def download(url):
	try:
		req = urllib2.Request(url)
		#この'Accept-encoding'の設定が絶対必要!!!
		req.add_header('Accept-encoding', 'gzip')
		r = urllib2.urlopen(req).read()
		return r
	except urllib2.URLError, error:
		return " (%s %s)" % (error.code, error.msg)

def params(d):
  """ Takes a dictionary of key, value pairs and generates a cgi parameter/argument string """
  p = ""
  for k, v in d.iteritems():
    p += "&%s=%s" % (quote_plus(k), quote_plus(v))
  return p

def search(command, vertical="web", version=1, start=0, count=10, lang="en", region="us", more={}):
  """
  command is the query (not escaped)
  vertical can be web, news, spelling, images
  lang/region default to en/us - take a look at the the
  YDN Boss documentation for the supported lang/region values
  """
  url = (SEARCH_API_URL % (vertical, version, quote_plus(command), start, count, lang, region)) + params(more)
  return download(url)
  #return simplejson.loads(download(url))


#sys.setdefaultencoding('UTF-8')
sys.stdout.write('Content-type: text/html; charset=UTF-8\n')
sys.stdout.write('Cache-Control: no-cache\n')
sys.stdout.write('\r\n\r\n')

sys.stdout.write("""
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="javascript">
<title>"Positive Search</title>
</head>

<body>""")

results=search("はてな","web",1,0,10,"jp","jp")

search_results = None
totalhits = 0
if results.has_key('ysearchresponse'):
	if results['ysearchresponse'].has_key('resultset_web'):
		search_results = results['ysearchresponse']['resultset_web']
	if results['ysearchresponse'].has_key('totalhits'):
		totalhits = results['ysearchresponse']['totalhits']

for res in search_results:
	sys.stdout.write(unicode(res['title']).encode('utf-8'))
	sys.stdout.write("<br>")

sys.stdout.write(str(totalhits))

sys.stdout.write("""
</body>

</html>""")