** 目次 [#u6fd608c]
 
 - [[概要>#h0f61a01]]
 - [[提案>#h0f61b01]]
 -- [[要望>#h0f61b02]]
 -- [[Googleカスタム検索+Google Web Search API の提案の内容>#h0f61b03]]
 - [[サンプル>#h0f61c01]]
 - [[実装方法>#h0f61d01]]
 -- [[Googleカスタム検索>#h0f61d02]]
 -- [[コンテキストXML>#h0f61d03]]
 -- [[アノテーションXML>#h0f61d04]]
 -- [[構築フロー>#h0f61d05]]
 - [[Google Web Search API>#h0f61d11]]
 -- [[リクエストパラメータ>#h0f61d12]]
 -- [[レスポンス>#h0f61d13]]
 -- [[トラブルシューティング>#h0f61d14]]
 - [[【重要】Google Web Search APIの制約>#h0f61e01]]
 -- [[検索件数がかけ離れている>#h0f61e02]]
 -- [[1ページは 8件まで、8ページ以上は取得できない>#h0f61e03]]
 - [[代替案1.Google Custom Search API>#h0f61f01]]
 - [[代替案2.Y!APIやBingAPI>#h0f61g01]]
 - [[まとめ>#h0f61h01]]
 
 ** 概要 [#h0f61a01]
 
 Google Web Search API、もしくは Google Custom Search APIを導入してみようと思っている方へ、
 弊社で悪戦苦闘した上に他の対応方法への変更を余儀なくされた経験をお伝えしたく、書いています。
                             アークウェブ 竹村
 
 
 ** 提案  [#h0f61b01]
 
 *** 要望  [#h0f61b02]
 
 要望としては、
 
 - あるディレクトリ配下に対して、ユーザーが入力したキーワードに対する全文検索結果を表示したい
 - かつ、各ページにタグを付けておき、タグで絞り込むようにしたい
 -- 検索対象のページ数は200件程度
 
 というものでした。
 
 まず、NAMAZU を提案したのですが諸事情で却下としました。
 利用できるのはPHPのみ、という状況です。
 
 そこで、外部のAPIにアクセスして検索結果を取得する方法を提案し、これが採用されました。
 それが『Googleカスタム検索+Google Web Search API』による検索です。
 
 *** Googleカスタム検索+Google Web Search API の提案の内容  [#h0f61b03]
 
 Googleカスタム検索は、コンテキストのXMLと、アノテーションのXMLを利用して
 任意のURL(Googleカスタム検索では ''サイト'' と呼びます)に対して、タグ(Googleカスタム検索では ''ラベル'' と呼びます)を指定できます。
 検索条件として、キーワードの他にラベルを指定してサイトを絞り込むことができるわけです。
 
 Google Web Search APIは、Googleカスタム検索のIDを指定して検索条件やページングの制御が可能です。
 
 この 2つを組み合わせて、Googleカスタム検索で検索対象のページを整備しておき
 ユーザーの検索条件からGoogle Web Search APIで検索結果を取得して表示する。
 プログラムはPHPで動作可能。
 
 という提案をしました。
 
 
 ** サンプル  [#h0f61c01]
 
 当時作ったサンプルが↓こちら。
 
 ▼APIを利用して検索結果を表示するサンプル
 http://okra.ark-web.jp/~takemura/public/google/custom_search/for_api.html
 
 #ref(sample.jpg);
 
 - 表示件数10件だとエラーになるのはAPIの制約です。
 - 何もせずそのまま検索すると、 ''「全件数」が168などとなりますが、実は全ページは41ページしかありません。''
 
 #blikimore()
 
 ** 実装方法 [#h0f61d01]
 
 サンプルを作る上で、必要となった資料をメモしておきます。
 
 *** Googleカスタム検索 [#h0f61d02]
 
 - 公式資料
 http://code.google.com/intl/ja/apis/customsearch/docs/dev_guide.html
 
 *** Googleカスタム検索|コンテキストXML [#h0f61d03]
 
 - 主にラベルを定義。
 ラベル名はTitleタグに正式名称を書いて、
 Labelタグのname属性には、「作業分類:a.清掃活動」というラベルの場合は「:」を「_」に変えて「作業分類_a.清掃活動」とする。
 ( : の他にも / も _ に変えておく)
 
  例:
      <Facet>
       <FacetItem>
         <Label name="作業分類_a.清掃活動" mode="FILTER">
           <Rewrite></Rewrite>
         </Label>
         <Title>作業分類:a.清掃活動</Title>
       </FacetItem>
     </Facet>
 
 *** Googleカスタム検索|アノテーションXML [#h0f61d04]
 
 - 主にページにラベルを貼る感じ。
 Annotationタグの子要素Labelタグには必ずGoogleカスタム検索のID(_cse_xxxxxxxx というヤツ)を指定すること。
 
  例:
   <Annotation about="okra.ark-web.jp/~takemura/public/google/custom_search/indexed_area/contents_001.html" score="1" timestamp="0x00049b6bdc3c22ea" href="ClRva3JhLmFyay13ZWIuanAvfnRha2VtdXJhL3B1YmxpYy9nb29nbGUvY3VzdG9tX3NlYXJjaC9pbmRleGVkX2FyZWEvY29udGVudHNfMDAxLmh0bWwQ6sXw4b3tpgI">
     <Label name="_cse_yfgako6fk48" />
     <Label name="sugudeki" />
     <Label name="rabit" />
     <AdditionalData attribute="original_url" value="okra.ark-web.jp/~takemura/public/google/custom_search/indexed_area/contents_001.html" />
   </Annotation>
 
 - アノテーションの制約事項
 http://code.google.com/intl/ja/apis/customsearch/docs/annotations.html#limits
 
 *** Googleカスタム検索|構築フロー [#h0f61d05]
 
 - Googleカスタム検索にアクセスする
 http://www.google.com/cse
 - 新しく検索エンジンを作る
 - メニューから「基本」より、検索エンジン IDを控えておく
 - メニューから「詳細設定」より、コンテキストXMLのダウンロード
 - コンテキストXMLをカスタマイズしてラベルを追加して、アップロード
 -- メニューの「絞り込み」にラベルが増えているのを確認
 - メニューから「詳細設定」より、アノテーションXMLのダウンロード
 - アノテーションXMLをカスタマイズしてページとラベルの組み合わせを定義して、アップロード
 -- メニューの「サイト」にページ一覧が増えており、ラベルと関連づいているのを確認
 - メニューから「インデックス作成」より、「個別の URL によるオンデマンド インデックス登録」にページのURLを列挙して登録
 (もしくは、「ウェブマスター ツールを使用してサイトマップを送信」からサイトマップを登録してから、「サイトマップによるオンデマンド インデックス登録」のプルダウンからサイトマップXMLを指定して登録)
 -- メニューの「プレビュー」から検索してみてヒットすることを確認
 
 
 *** Google Web Search API [#h0f61d11]
 
 公式資料
 http://code.google.com/intl/ja/apis/websearch/docs/#fonje
 
 *** Google Web Search API|リクエストパラメータ [#h0f61d12]
 
 公式資料
 http://code.google.com/intl/ja/apis/websearch/docs/#fonje
 
 - APIのベースURL
 https://ajax.googleapis.com/ajax/services/search/web
 ↑コレにパラメータを付与していく
 
 - Standard URL Arguments
 -- q: 検索条件。必須。(なお、カスタム検索のラベルを検索する場合は、このqに検索条件に続けて more:ラベル名 と入れる。複数のラベルの場合は、「more:ラベルa more:ラベルb」 のようにする)
 -- v: 1.0 を入れる。必須。
 -- userip: テスト時にアクセス元IPを指定しておく
 -- rsz: 表示件数。デフォルト4で最大8。filtered_cseをどうかすると10になるらしいが、filtered_cseってなに?分からないので8という認識。
 -- hl: 使用言語。hl=ja にしとけば問題ない
 -- key: 下記で作ったキーを指定する
 http://code.google.com/intl/ja/apis/loader/signup.html
 -- start: ページングする時に使用
 -- callback: 使わない
 -- context: 使わない
 
 - Web Search Specific Arguments
 -- cx: CSE_IDを指定 (マイ検索エンジンのコントロールパネルに書いてある検索エンジン IDを指す。コロンで区切られてるけど気にせず全部がID)
 -- cref: コンテキストXMLを指定できる。…が、cxがあれば指定しなくて良い。無視。
 -- safe: デフォルトでいい。
 -- lr: lr=lang_ja でいい。
 -- filter: 重複は必要ないのでデフォルトでいい。
 -- gl: 無視
 
 - 注意事項
 -- 【重要】APIを投げる際、必ずRefererを指定する
 -- qに指定するキーワードはUTF8に変換しておくこと
 -- qに指定するラベルの「 : / 、 ・ (」はすべて「_」にする (例外として「)」は「」に置換)
 
 
 *** Google Web Search API|レスポンス [#h0f61d13]
 
 - responseData->results->[0]->title: タイトル
 - responseData->results->[0]->content: 本文の一部
 - responseData->results->[0]->unescapedUrl: リンクのhrefに指定するときに利用
 - responseData->results->[0]->url: 画面に表示するときに利用
 - responseData->results->[0]->cacheUrl: キャッシュのリンク先が必要な場合に利用
 - responseData->cursor->estimatedResultCount: ''概算'' 全結果総数
 - responseData->cursor->currentPageIndex: 現在のページ数
 - responseData->responseStatus: ステータス。200が正常。
 
 
 *** Google Web Search API|トラブルシューティング [#h0f61d14]
 
 - responseStatusが 400 になってしまう。
 →対応方法:cx の設定が誤っている可能性がある。検索エンジンIDを確認してみよう
 
 - 「Suspected Terms of Service Abuse. Please see http://code.google.com/apis/errors」というエラーで、responseStatus が 403 になってしまう。
 →対応方法:valid HTTP referer がセットされていないのが問題。APIを投げる際にリファラーをセットしよう
 
 
 ** 【重要】Google Web Search APIの制約 [#h0f61e01]
 
 さて、ここが一番重要な部分です。
 Google Web Searc APIのクリティカルな制約が 2つあります。
 
 - 検索件数がかけ離れている
 - 1ページは 8件まで、8ページ以上は取得できない
 
 詳しく説明します。
 
 *** 検索件数がかけ離れている [#h0f61e02]
 
 Google Web Search API で返ってくる検索結果総数は、
 estimatedResultCount という値に該当します。
 
 estimatedResultCount はあくまで概算に過ぎない。というのは公式資料にあります。
 http://code.google.com/intl/ja/apis/websearch/docs/reference.html#_property_GSearch
 > estimatedResultCount - supplies the estimated number of results that match the current query. Note that this value will not necessarily match the similar value thats visible on the Google.com search properties. 
 
 また、estimatedResultCount で検索すると
 
 http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/a3e074c5c45556a7/738033c96cae5aa8?lnk=gst&q=estimatedResultCount#738033c96cae5aa8Google
 > It seems that on average, the API returns about 55% of the estimated
 > number of results that google.com returns.
 
 と書いていますが、
 私が案件で構築したものは200ページに対して検索結果が5000にもなりました!
 
 ここまでかけ離れた件数では使えません。
 
 
 *** 1ページは 8件まで、8ページ以上は取得できない [#h0f61e03]
 
 1ページは最大 8件までですが、 ''8ページまでしかAPIで取得できません。''
 
 それ以上取得しようとするとGoogleからのレスポンスが
 「out of range start」と言われてresponseStatus が 400 で返ってきます。
 
 
 この"out of range start"でググってみると、
 
 http://code.google.com/p/googleas3api/issues/detail?id=2
 (APIKeyについて書いてますが、APIKeyを指定してもダメ。やってみました。
 comment2でtried but...とも書いているので関係ないとみた)
 
 http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/ed90e221e97d9daf/b02f6551cdd7154a?lnk=gst&q=out+of+range+start#b02f6551cdd7154a
 無理ですと言われている例。
 
 http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/45d58a1aee15fb48/f6769a02d2a039b9?lnk=gst&q=out+of+range+start#f6769a02d2a039b9
 無理だと分かって怒ってる例。
 
 http://code.google.com/p/google-ajax-apis/issues/detail?id=315
  ↓
 http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/184bc00b8c1ce5f9
 1ページ4件の場合8ページまでで32件しか取れない。という話
 
 総括して、上限は64件以上は取れない模様です。
 
 
 ** 代替案1.Google Custom Search API [#h0f61f01]
 
 公式資料
 http://code.google.com/intl/ja/apis/customsearch/v1/overview.html
 
 *** やってみた [#h0f61f02]
 
 - 検索件数は Google Web Search API と大差ない。
 - 1ページは 10件まで、100件以上は取得できない
 
 - その他制約
 -- 1日あたり100クエリー以上の検索があった場合1000クエリーあたり $5 課金される
 
 【結果】
 ダメだコリャ。
 
 
 ** 代替案2.Y!APIやBingAPI [#h0f61g01]
 
 Y!のウェブ検索を調べてみましたが
 http://developer.yahoo.co.jp/webapi/search/websearch/v2/websearch.html
 これには「ラベル」の概念がないので、自由に絞り込みができないので要件を満たしません。
 また、Y!は上限100(プレミアで5万)件/dayの制約がある。 http://developer.yahoo.co.jp/webapi/search/
 
 Goo、APIがない模様。
 http://labs.goo.ne.jp/
 
 ライブドア、それっぽいAPIはなさそう。
 http://wafl.net/apis/search?keywords=%E3%83%A9%E3%82%A4%E3%83%96%E3%83%89%E3%82%A2
 
 Bing API というのはあるが、Y!と同様で「ラベル」がない。
 http://www.bing.com/developers/s/API%20Basics.pdf
 また、Bing APIは必須項目が厳しい模様。 http://mbnk.blog120.fc2.com/blog-entry-209.html
 
 【結論】
 「ラベル」の概念のある検索APIは見つからなかった。
 
 
 ** まとめ [#h0f61h01]
 
 Googleカスタム検索の「ラベル」の概念は、他の検索APIにないすばらしい絞り込みの機能だと思うのですが、
 サポートするAPIの制約で結局利用できませんでした。非常に残念なことです。
 
 
 以上、この同じ問題でムダに時間を使ってしまうシステム担当者を少しでも救えるようであれば幸いです。
 
 
 #blikifooter(竹村)
 
 ----
 tag:[[API>tag/API]], [[検索>tag/検索]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

アークウェブのサービスやソリューションはこちら