Андрей Друченко
Поиск Yandex.XML в PHP
Почти всегда при разработке сайта возникает задача поиска по его содержимому. Будь-то поиск по каким-то данным из БД, или же поиск по статическим файлам на сервере — обычно задача сводится к полнотекстовому поиску по всей информации на сайте.Решений здесь можно придумать великое множество, среди того что приходит в голову можно выделить:
- Свое решение путем создания простого текстового индекса для каждого из текстовых файлов сайта (обычно — html), и самый простой булевый поиск на совпадение/не совпадение слов запроса словам из индекса. Тут же можно реализовать элементарный язык запросов, который, например будет понимать OR и AND
- В случае хранения информации в СУБД MySQL >=3.23.23, можно попробовать организовать поиск используя встроенный FULLTEXT Search движок MySQL, определив колонки для поиска как индексы типа FULLTEXT. Такой поиск представляется весьма заманчивым, т.к. поддерживает сразу же несколько режимов (BOOLEAN, NATURAL LANGUAGE, QUERY EXPANSION) и довольно просто реализуется на уровне элементарных запросов к СУБД. Также, начиная с версии 5.1 в MySQL можно писать свои поисковые движки, и один из них следует упомянуть — SphinxSearch. В то же время, основным недостатком является время добавления нового документа в базу, и время поиска. На shared хостингах это время может быть сравнимо с десятками секунд, а то и минут — что выглядит ужасно.
- Сторонние решения, в виде внешних библиотек и подключаемых модулей к php. Из известных мне систем — mnogoSearch, Apache Lucene. Но для установки первого требуются дополнительные бинарные модули к PHP, которые за просто так на shared хостинге вам никто не поставит, ну а второй — до мозга костей написан на Java. Осюда вывод, что подобные системы подходят для солидных проектов, где можно себе позволить заплатить за colocation или за виртуальный сервер и ставить там все что душе угодно.
Все вышеперечисленные решения никуда не годятся, если надо быстро поставить качественный поиск на средних размеров сайт на shared хостинге. Лично я, пришел к решению на базе Yandex.XML — быстро устанавливается, хорошо интегрируется в дизайн сайта, и главное — хорошо ищет (оно и не удивительно, ведь это поиск от Яндекса ;)
Описание и лицензия.
Если вкратце, то Яндекс.XML это XML сервис который принимает на вход POST/GET запросы и на выходе отдает сформированный XML документ с результатами поиска, с которым потом можно делать что угодно (обычно далее идет преобразование XSLT и на выходе нужный нам HTML).Для активации сервиса для вашего сайта нужно всего лишь зарегистрировать IP адрес сайта в базе Яндекса. После этого станет доступен бесплатный вариант поиска, который предполагает не более 500 запросов в сутки с одного IP.
Бесплатный вариант лицензии Яндекс.XML также предполагает размещение фразы «Поиск реализован на основе Яндекс.XML» вверху результатов поиска на вашем сайте.
В целом, это все что требуется знать перед началом.
Установка
Разработчику, прежде всего, следует начать с Документации по Яндекс.XML, там же есть интересные примеры использования, примеры поисковых запросов, XSLT файлы с парочкой дизайнов, и даже программный код, но увы, на Perl.Перед началом, нам надо скачать один из XSLT-дизайнов (маньякам — предлагается потратить день-другой на написание своего;)
Итак, код для PHP4, с XSLT парсером Sablotron:
<?php
// для удобства
function request($name, $default_value = FALSE) {
return (isset($_REQUEST[$name]) && !empty($_REQUEST[$name]))?$_REQUEST[$name]:$default_value;
}
$query = request("query"); // Поисковый запрос
$page = request("page", 0); // Номер страницы
$OUTPUT = ""; // Переменная будет содержать результат поиска.
if (FALSE !== $query)
{
// Включаем стандартный компонент из PEAR для последующего формирования
// GET запроса к Яндекс.
require_once 'HTTP/Request.php';
$req = new HTTP_Request("http://xmlsearch.yandex.ru/xmlsearch");
$req->setMethod(HTTP_REQUEST_METHOD_GET);
// Следующий код нужен для нормальной поддержки пейджинга поисковых результатов,
// а также для преобразования UTF-8 строки запроса в кодировку Windows-1251.
// $DOMAIN_NAME это имя хоста, например myhost.com.ua
if (strstr($query, "host=") === FALSE )
$full_query = $query.' << host="'.$DOMAIN_NAME.'"';
else
$full_query = stripslashes(iconv("UTF-8", "CP1251", $query));
$req->addQueryString('query', htmlspecialchars($full_query));
$req->addQueryString('page', $page);
$req->addQueryString("maxpassages", 2);
$req->sendRequest(); // Посылаем GET запрос к Яндексу
$xml_data = $req->getResponseBody(); // Получаем XML ответ от Яндекса
// Получаем содержимое нашего XSL-дизайна
$xsl_data = file_get_contents("search.xsl");
$arguments = array('/_xml' => $xml_data,'/_xsl' => $xsl_data );
// Создание XSLT процессора
$xh = xslt_create();
// Обратываем XML запрос
$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
if ($result) {
$OUTPUT = $result; // передаем результирующий HTML на выход
} else {
//Обрабатываем ошибки
$OUTPUT.= "Sorry, ".$el[file]." could not be transformed by $xsl_file,";
$OUTPUT.="the reason is that " . xslt_error($xh) . " and the error code is " . xslt_errno($xh);
}
xslt_free($xh);
}
echo($OUTPUT); // Выводим результаты поиска.
?>
Для работоспособности кода нужно установить себе пакет PEAR/HTTP (http://pear.php.net) вместе с его зависимостями (HTTP_Request, Net_Socket), а также поместить в файл search.xsl — XSLT дизайн. В данном примере использовался вот этот
Заключение
Код местами кривоват, и его можно улучшить — но нужный функционал у нас есть. Единственное, с чем надо поиграться — это серией параметров которые передаются Яндексу — page, maxpassages, groupby, sortbyЕдинственный минус при использовании данного сервиса — это то что ваш сайт УЖЕ должен быть проиндексирован Яндексом :)
Мой пример на Яндекс.XML
Ссылки
- Проект Яндекс.XML
- PEAR Package for simple access to Russian search engine Yandex over Yandex XML
- Лицензия Яндекс.XML
- Документация по Яндекс.XML
- XSLT-дизайны Яндекса
Последние комментарии:
Пример работы | Антон |
---|---|
Ладно пример работы, код лучше покажите. Да и кого есть решения поиска по регионам И поиска картинок? |
|
Re: Недоработка однако | Автор |
Насчет глюков на 17-й странице, недавно натолкнулся на ситуацию когда нельзя листать дальше 50-й страницы в Яндекс.Маркет, судя по всему — XML поиск от Яндекса подобным же образом ограничивает пейджинг в своих результатах. Этакая защита от роботов |
|
re: Чё за? | автор |
Это синтаксис подсветки кода. В нашем блоге используется движок ВакоВики, более подробно можно прочитать здесь http://wackowiki.com/WackoDokumentacija/Formattery |
|
Чё за? | Anton |
И как это понимать? -> PHP/HTML код для подсветки надо заключать в Formatter «highlight/php/html» not found(php/html)<? ?> |
|
Недоработка однако | Anton |
В скрипте есть глюк пример с сайта www.zir.com.ua приведённого автором. По запросу с 17-й страницы ничего не получаем %) http://zir.com.ua/search/?query=%d0%b3%d0%bb%d0%b0%d0%b7%d0%b0%20%3C%3C%20host=%22www.zir.com.ua%22&groupby=mode%3D.attr%3D.groups-on-page%3D.docs-in-group%3D.curcateg%3D&page=17 |
|
Обсудить (комментариев: 25)