Поисковое API для PHP (Flash, Java и других)

    Задача: организовать поиск по всему сайту затратив как можно меньше усилий и оформить результаты в своем стиле.

    Рассуждение
    Есть различные серверные системы для организации полнотекстового поиска индексируя сайт, индексирую базу данных. Но их надо устанавливать на своем сервере, настраивать, а некоторые из них еще и платные.
    В какой-то момент решил воспользоваться Google Ajax Search API через JavaScript, но тут вид результатов менять достаточно сложно, да и еще надо делать запросы в другой домен при помощи javascript.

    Решение
    В итоге набрел на странице Google AJAX Search API в раздел Code Snippets и все стало просто: немного кода на php и полнотекстовый поиск по любому сайту готов.


    PHP


    Приведен слегка упрощенный фрагмент кода. Конечно, хорошо бы сделать проверку на доступность сервера ajax.googleapis.com в данный момент.

    <?php
    //Получаем настройки поискового запроса
    $data    = MyDB::get() -> selectOne('*',self::TABLE,'`id_mod` = '.$this->id_mod);

    //На каком сайте ищем?
    $sireUrl = $data['url'];

    //Данные полученные от пользователя
    $sigs = array(
      'q'    => array('type' => 'string', 'required' => false),
      'start'  => array('type' => 'integer', 'required' => false)
    );
    $reqData = SpeData::sanitize_vars($this->queryArray, $sigs, 'RequestException');    
    $q     = urlencode($reqData['q'].' site:'.$sireUrl);
    $start   = empty($reqData['start']) ? 0 : $reqData['start'];

    //Отправляем запрос гуглу, собственно это основаня часть :)
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=$q&rsz=large&hl=ru&start=$start");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_REFERER, "http://$sireUrl/");
    $body = curl_exec($ch);
    curl_close($ch);

    //Ответ получили, в принципе, зада выполнена :)
    $json = json_decode($body);
    //На этом этапе можно сделать print_r($json) и все станет понятно
    //Но что бы в smarty было проще разобрать результаты, можно преобразовать его в следующий вид

    $search = array();

    //Результаты поиска
    if (count($json -> responseData -> results) == 0) { //если ничего не найдено
      $search['result'] = false;
    } else {
      foreach ($json -> responseData -> results as $v) {
        $search['result'][] = array(
          'GsearchResultClass'   => $v -> GsearchResultClass,
          'unescapedUrl'       => $v -> unescapedUrl,
          'url'           => $v -> url,
          'visibleUrl'       => $v -> visibleUrl,
          'cacheUrl'         => $v -> cacheUrl,
          'title'         => $v -> title, //заголовок найденого документа (индексируется ведь не только html-странички)
          'titleNoFormatting'   => $v -> titleNoFormatting,
          'content'         => $v -> content //выдержка из текста документа
        );
      }
    }

    //Список ссылок на остальные результаты поиска
    if (count($json -> responseData -> results) == 0) { //если ничего не найдено
      $search['pages'] = false;
    } else {    
      $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REDIRECT_URL'].'?q='.$reqData['q'];
      foreach ($json -> responseData -> cursor -> pages as $v) {
        $search['pages'][] = array(
          'start'   => $v -> start,
          'startUrl'  => $url.'&start='.$v -> start,
          'label'   => $v -> label
        );
      }
    }

    //Общая информация о результатах поиска
    $currentPageIndex = $json -> responseData -> cursor -> currentPageIndex;
    $search['info'] = array(
      'q'            => $reqData['q'],
      'estimatedResultCount'   => $json -> responseData -> cursor -> estimatedResultCount,
      'moreResultsUrl'    => $json -> responseData -> cursor -> moreResultsUrl,
      'currentPageIndex'     => $currentPageIndex,
      'currentLabel'      => $currentPageIndex + 1,
      'startResult'      => $currentPageIndex * 8 + 1,
      'endResult'        => ($currentPageIndex * 8 + 1) + count($search['result']),
      'next'          => (count($search['pages']) > $currentPageIndex + 1) ? $search['pages'][$currentPageIndex + 1]['startUrl'] : false,
      'prev'          => ($currentPageIndex) ? $search['pages'][$currentPageIndex - 1]['startUrl'] : false
    );
      

    //Все готово
    MySmarty::get() -> assign('search', $search);

    ?>


    * This source code was highlighted with Source Code Highlighter.


    SMARTY


    Использую ограничители «{{» и «}}» что бы отличать smarty от javascript

    {{if !$search.result}}
      По запросу <b> {{$search.info.q}} </b> ничего не найдено или в данным момент поисковый сервис недоступен.
    {{else}}
      Результаты <b>{{$search.info.startResult}} - {{$search.info.endResult}}</b> из примерно <b>{{$search.info.estimatedResultCount}}</b> для <b>{{$search.info.q}}</b>
      <br />
      <br />

      {{section name=i loop=$search.result}}
        <a href="{{$search.result[i].url}}">{{$search.result[i].title}}</a><br />
        {{$search.result[i].content}}
        <br />
        <br />

      {{/section}}

      <br/>

      {{if $search.info.prev}}
        <a href="{{$search.info.prev}}">Предыдущая</a>    
      {{/if}}
      
      
      {{section name=i loop=$search.pages}}
        {{if $search.info.currentLabel == $search.pages[i].label}}
          {{$search.pages[i].label}}
        {{else}}
          <a href="{{$search.pages[i].startUrl}}">{{$search.pages[i].label}}</a>
        {{/if}}
      {{/section}}
      
      {{if $search.info.next}}
            <a href="{{$search.info.next}}">Следующая</a>
      {{/if}}

    {{/if}}


    * This source code was highlighted with Source Code Highlighter.


    Вот и получили хороший поиск по любого рода данным (html,doc,pdf и остальные документы по которым ищет google).

    Так же есть удобный инструмент для тестов Google Ajax Api Playground.

    Хабралюди, если вы в курсе, подскажите пожалуйста, как обстоят дела с соглашениями об использовании этого поискового API. Должен ли я на страничке с результатами указывать что пользуюсь поиском google, или делать еще что-либо подобное?

    Спасибо за внимание.

    P.S. Это мой первый пост на хабре, если что-то сделал не так скажите, исправлю :)
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 6
      0
      спасибо, уже давно маялся с гугловым поиском, через парсинг. Правда, у меня немного другая задача — нужно по кивордам выгребти позицию в гугле ;)
        +1
        Посмотрите analyser.hohli.com/url, тут при помощи Javascript много чего интересного о сайте добывают.

        +1
        Нужно указывать, что поиск осуществлен с помощью Гугль. Хотя бы просто из уважения :)

        Пост полезен. Спасибо.
          0
          Спасибо всем кто повысил карму, перенес в блок Google
            0
            Ммм… а как насчет ограничений на использование (лимит)? Наверняка уж не «бери сколько унесешь» =)
              0
              За один раз возвращает максимум 8 результатов, начиная со значения start переданного get'ом. Результат получается эквивалентен запросу гуглу типа: «запрос site:habrahabr.ru»

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое