Googleで検索すると、「もしかして:」と検索キーワードの候補が表示されることがある。また、Firefoxなどブラウザの検索バーにキーワードを打ち込むと、狙いすましたような候補が出てきて驚くことがある。

これを提供しているのがGoogle Suggest。APIとして公開されているので、webアプリからも簡単に使うことができる。最近意図的にRubyばっかり書いているので、Rubyを使ったサンプルをメモがてら晒すことにする。

追記

【2009-10-22 追記】

一番書く必要があった「リクエストURL」について書き忘れていたので追記。

suggestの取得

suggest.rb
# -*- coding: utf-8 -*-
require 'net/http'
require 'cgi'

word = 'きのう何食べた'

http  = Net::HTTP.new('www.google.co.jp', 80)
query = "/complete/search?output=toolbar&q=#{CGI::escape(word)}"
req   = Net::HTTP::Get.new(query)
res   = http.request(req)

puts res
% ruby suggest.rb > suggest.xml
suggest.xml
<?xml version="1.0"?>
<toplevel>
<CompleteSuggestion><suggestion data="きのう何食べた レシピ"/><num_queries int="44100"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた よしながふみ"/><num_queries int="64800"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた 限定版"/><num_queries int="44900"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた 3巻"/><num_queries int="163000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた 2巻"/><num_queries int="266000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた レシピ そうめん"/><num_queries int="6430"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた ジャム"/><num_queries int="12400"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた そうめん"/><num_queries int="12100"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた 」"/><num_queries int="289000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="きのう何食べた うなぎ"/><num_queries int="29500"/></CompleteSuggestion>
</toplevel>
Suggestion

Firefoxの検索バーの結果と突き合わせてみると、同じデータを使ってることがわかる。

Rubyで利用する

XMLが返ってくるので、要素を取り出して配列に突っ込んでやれば使い道はあるだろうか。

parse_suggest.rb
# -*- coding: utf-8 -*-
require 'rexml/document'

# google suggestのXMLをparseして「もしかして」単語の配列を返す
def parse_suggestion xml
  doc = REXML::Document.new xml
  suggested_words = []
  doc.get_elements('//toplevel/CompleteSuggestion').each do |e|
    suggested_words << e.elements['suggestion'].attributes['data']
  end
  suggested_words
end

puts parse_suggestion(File.open('suggest.xml').read)

XMLそのものについてもREXMLライブラリについてもちゃんと理解していないので、この辺は引き続き要勉強。

リクエストURIについて

【2009-10-22 追記】

suggest.rbではリクエスト先のホストを「’www.google.co.jp’」と指定している。日本語での検索をする場合は必ずこのホストへリクエストする必要がある。それ以外のホスト名(後述)にリクエストしても正常に処理されるが、英語版での結果を返すため…

  • 日本語マルチバイト文字をリクエスト

    →結果なし

  • ASCIIキャラクタをリクエスト

    →英語版の結果

…となる。試したホストは以下の通り。

キーワードに「sequel」を指定した場合の、日本語版と英語版の結果を貼っておく。

日本語
<?xml version="1.0"?>
<toplevel>
<CompleteSuggestion><suggestion data="sequel 2"/><num_queries int="52800000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel ruby"/><num_queries int="287000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel 2 価格"/><num_queries int="51800"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequelae"/><num_queries int="1280000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel pro"/><num_queries int="2320000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel 2 体験版"/><num_queries int="14300"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel 意味"/><num_queries int="37000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequelink"/><num_queries int="14400"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel 2 アカデミック"/><num_queries int="1800"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel 価格"/><num_queries int="56900"/></CompleteSuggestion>
</toplevel>
英語
<?xml version="1.0"?>
<toplevel>
<CompleteSuggestion><suggestion data="sequelae"/><num_queries int="2380000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel to the dark knight"/><num_queries int="1610000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel to typee"/><num_queries int="6930000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel pro"/><num_queries int="4390000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequelae definition"/><num_queries int="373000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel server"/><num_queries int="446000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequels"/><num_queries int="4660000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequella"/><num_queries int="69700"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel to breaking dawn"/><num_queries int="211000"/></CompleteSuggestion>
<CompleteSuggestion><suggestion data="sequel to twilight"/><num_queries int="2990000"/></CompleteSuggestion>
</toplevel>

【2010-08-11 追記】

クエリパラメータに「hl=ja」を追記すると日本語の結果が返ってくる。詳細はまたいずれ。

Google Suggest API

http://blogoscoped.com/archive/2006-08-17-n22.html

職業プログラマの戯言 | google suggest api

http://kommy.s254.xrea.com/blog/log/eid58.html

RubyでXML操作: Netsphere Laboratories

http://www.nslabs.jp/ruby-rexml.rhtml