developer.co.ua

Holy Copypasters

Комментарии к статье «Поиск Yandex.XML в PHP»

Пример работы Антон
Ладно пример работы, код лучше покажите.
Да и кого есть решения поиска по регионам
И поиска картинок?

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

проблема с PHP 5 Anton
Скрипт приведённый в статье работать с PHP5 не будет.
Выдаёт ошибку вида «PHP Fatal error: Call to undefined function xslt_create()»
ЧтО жЕ дЕлАтЬ?
В этом случае есть два выхода:

1. Переписать код ваших скриптов, используя XSL.
2. Подключить дополнительный файл, который позволяет использовать функции xslt_create & etc в php5. Для этого нужно подключить файл xslt-php4-to-php5.php в скрипт в котором выполняется xslt_create, например, так:
<?PHP
      
if (version_compare(PHP_VERSION,'5','>='
      &&
extension_loaded('xsl'))
      require_once(
'xslt-php4-to-php5.php');
?>


Второй вариант лучше всего рассматривать как временый, т.к. адаптировав свой код к PHP 5, вы увеличите производительность работы ваших проектов.

А вот и сам код xslt-php4-to-php5.php:
<?PHP
$xslArgs
=null;
function 
xslt_create() {return new xsltprocessor();}
function 
xslt_errno($xh) {return 7;}
function 
xslt_error($xh) {return '?';}
function 
xslt_free($xh) {unset($xh);}
function 
xslt_process($xh,$xmlcontainer,$xslcontainer,$resultcontainer=null,$arguments=array(),$parameters=array())
{
//See also: http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/
 //Based on: http://www.php.net/manual/ref.xsl.php#45415
 
$xml=new DOMDocument();
 
$basedir=$xh->getParameter('sablotron','xslt_base_dir');
 if (
$basedir && ($workdir=getcwd()))
    if (!
is_dir($basedir))
    {
        
$basedir=dirname($basedir);
        
chdir($basedir);
    }
 if (
substr($xmlcontainer,0,4)=='arg:')
  
$xml->loadXML($arguments[substr($xmlcontainer,4)]);
 else 
$xml->load($xmlcontainer);
 
$xsl=new DOMDocument();
 if (
substr($xslcontainer,0,4)=='arg:')
  
$xsl_=&$arguments[substr($xslcontainer,4)];
 else 
$xsl_=file_get_contents($xslcontainer);
 
$xsl->loadXML(str_replace('arg:/','arg://',$xsl_));
 
$xh->importStyleSheet($xsl);
 global 
$xslArgs;
 
$xslArgs=$arguments;
 foreach (
$parameters as $param=>$value)
  
$xh->setParameter('',$param,$value);
 
$result=$xh->transformToXML($xml);
 if (isset(
$resultcontainer))
  
file_put_contents($resultcontainer,$result); 
 if (
$basedir && $workdir)
  
chdir($workdir);
 if (isset(
$resultcontainer))
  return 
true;
 else return 
$result;
}
function 
xslt_set_base($xh,$base) {$xh->setParameter('sablotron','xslt_base_dir',str_replace('file://','',$base));}
function 
xslt_set_encoding($xh,$encoding) {} //Manual encoding, or use xsl:output @encoding in XSL document
function xslt_set_error_handler($xh,$handler) {}

class 
xslt_arg_stream
{
 public 
$position;
 private 
$xslArg;
 function 
stream_eof() {return $this->position>=strlen($this->xslArg);}
 function 
stream_open($path,$mode,$options,&$opened_path)
 {
  
$this->position=0;
  
$url=parse_url($path);
  
$varname=$url['host'];
  global 
$xslArgs;
  if (isset(
$xslArgs['/'.$varname]))
   
$this->xslArg=&$xslArgs['/'.$varname];
  elseif (isset(
$xslArgs[$varname]))
   
$this->xslArg=&$xslArgs[$varname];
  else return 
false;
  return 
true;
 }
 function 
stream_read($count)
 {
  
$ret=substr($this->xslArg,$this->position,$count);
  
$this->position+=strlen($ret);
  return 
$ret;
 }
 function 
stream_tell() {return $this->position;}
 function 
url_stat() {return array();}
}

stream_wrapper_register('arg','xslt_arg_stream');
?>

Для пОпуасов! Anton
Нужно просто кавычки поменять " на '
$post_string = "<?xml version='1.0' encoding='windows-1251'?>
<request>
    <query>$full_query</query>
    <page>$page</page>
</request>";

нех ваще писать не рабочие скрипты Папуас
люди учатся по вашим скриптам а вы вот вам код но найдите че нужно подправить и потом гадай где это нужно делать и в чем ошибка

вот почему лучше всего мануалы там гоффно не рабочего не пишут

и кстати ошибка вот здесь

$post_string = "<?xml version="1.0" encoding="windows-1251"?>
<request>
    <query>$full_query</query>
    <page>$page</page>
</request>";


записывать надо по другому php ругается на синтаксическую ошибку ( прогер херов )

Так пример же там есть diktator
Так Яндекс даёт пример поиска по сайту на php – http://xml.yandex.ru/games/site-search-php.html Я попробовал установить его на свой сайт, всё работает...

XML Некто
Видимо, не работает потому, что не подключены какие-нибудь библиотеки. Объяснили бы вкратце про Sablotron.

Алексей
Сделал всё как надо и....
Call to undefined function xslt_create() in /home/ukrwarez/domains/musorka.com.ua/public_html/search/search.php on line 47
Кто может, помогите!
ася: 44144137
мыло: info@ach.org.ua

2Николай: Спасибо за дельные замечания Автор
Дополнил статью упоминанием дополнительных PEAR пакетов и исправил опечатку !
Спасибо.

Юмор понял Николай
Да, скрипт рабочий!
Проблема легко решается.

В самом начале советую вставить это:
ini_set(«include_path», '/путь-до-PEAR-php:' . ini_get(«include_path») );

Далее, установить PEAR модули:
http://pear.php.net/package/HTTP/
http://pear.php.net/package/HTTP_Request/
http://pear.php.net/package/Net_Socket/

После исправить ошибки в коде, особенно поставить пропущенную скобку внизу, перед echo($OUTPUT):
<?
...
xslt_free($xh);
}
echo(
$OUTPUT); // Выводим результаты поиска.
?>

Ну и запускать, как:

script.php?query=ваш-запрос !;)


Всем удачи! :)

P.S. Даже без знаний php, только по логике можно его установить и настроить!
Проверенно на собственном опыте! :)

Не понял юмора Николай
Понимаю конечно, что продвинутые кодеры сразу же понимают что и куда дописывать, но о простых смертных можно тоже позаботится?
Или нет уже добрых людей, готовых подсказать рабочее решение?

P.S. Ну, вот как тут например он работает? http://zir.com.ua/
Кстати, удачно интегрирован!

PHP XML Дмитрий
Не работает код :(

У меня не работает!! Devochka
Вообщем,я не совсем активный программист в веб,
но очень хочу такой поиск на свеом сайте.
Я попыталсь использовать Ваш код- не работает.

запросы отправляю, поулчаю в xml, а обработать не получается,
помогите плиз.

Поиск по сайту Юрий
Можно сделать еще проще. Добавить свой сайт в поисковую систему новотеки.

Divoll
То что страницы должны быть проиндексированы яндексом – хоть и единственный, но огромный недостаток...
При наличии строгой структуры сайта/данных – проще организовать поиск по MySql.
Тормоза поиска по MySql – вопрос организации структуры базы, построения индексов и собственно самого запроса...
На предыдущей работе столкнулись с поиском по нескольким табличкам(криво заджойненым) – изначально поисковый запрос выполнялся выполнялся 8–15 секунд в зависимости от загрузки сервера.
После небольшой реструктуризации БД и оптимизации запроса поисковый скрипт(уже весь скрипт – с несколькими запросами) стал отрабатывать за доли секунды.
При этом неоспоримым плюсом поиска по MySql(само собой для локального сайта) является актуальность информации – тогда как у Яндекса индексы на сегодня обновляются в лучшем случае раз в неделю...
Также плюс MySql – полнота охвата информации: зачастую при наличии большого кол-ва страниц(более 100 000 например) для внесения всех страниц в индекс яндексу нужно как минимум 3 месяца, а обновление проиндексированных страниц происходит еще медленнее.
То есть для себя я вывод сделал: яндекс XML рулит при создании небольших сайтов со статичной информацией...
Во всех остальных случаях для адекватного поиска необходимо учитывать динамику изменения данных – чего поиск по весьма статичным индексам яндекса не дает...

xml.yandex.ru POST запрос Юрий
<?
$host
"freeware32.ru";

function 
print_pager($found$reqid$page$query_search)
{
    
$links_on_page 10;         
    if (
$page != 0){
    print 
"<a href='?page=" ;
    print 
$page "&query_search=" 

$query_search.
 
"&request=$reqid'>&larr;&nbsp;предыдущая</a>&nbsp;";
    }
    print 
" страница № ";
    print 
$page 1;
    if (
$found > ($page 1) * $links_on_page)
    {
    print 
" <a href=?page=";
    print 
$page "&query_search=" 

$query_search 

"&request=$reqid>следующая&nbsp;&rarr;</a>&nbsp;";
    }
    
}
?>
<div>Поиск по сайту</div>
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td align="left" valign="middle" class="row">
<form method="get" action="">
<input type="hidden" name="host" value="<?print $host;?>"></input>
<input type="text" name="query_search" size="20" maxlength="255" 
value="<?if (isset($_GET['query_search'])){print $_GET['query_search'];}?>">
</input>
<input type="submit" name="sa" value="Поиск по сайту"></input>
</td>
</tr>
<tr>
<td>
<?
if (isset($_GET['query_search']))
{
$query_search $_GET['query_search'];
if (isset(
$_GET['page']))
{
$page $_GET['page'];}
else
{
$page 0;}
$full_query $query_search "&lt;&lt;host=&quot;$host&quot;"
$post_string "<?xml version="1.0" encoding="windows-1251"?>
<request>
    <query>$full_query</query>
    <page>$page</page>
</request>"
;

$service_port getservbyname ('www''tcp');
$address gethostbyname ('xmlsearch.yandex.ru');
$socket socket_create (AF_INETSOCK_STREAMSOL_TCP);
$result socket_connect ($socket$address80);
    
$in  "POST /xmlsearch/ HTTP/1.0rn";
    
$in .= "Host: xmlsearch.yandex.rurn";
    
$in .= "Content-type: text/xmlrn";
    
$in .= "Content-Length: ".strlen ($post_string)."rn";
    
$in .= "rn";
    
$in .= $post_string;
    
$in .= "rnrn";
    
$out '';
    
$response '';


    
socket_write ($socket$in);
    while (
$out socket_read ($socket2048)) 
    {
        
$response .= $out;
    }
    
    
socket_close ($socket);
    
$sParrentSep '/rnrn/';    
    
$ssplit preg_split ($sParrentSep$response2);
    
$xml $ssplit[1];    
    
$xml DOMDocument::loadXML($xml);

    
$xmlpath = new domxpath($xml);
    
$found $xmlpath->query("/yandexsearch/response/found[@priority='all']");
    if (
$found->length 0){
    
$found $found->item(0)->nodeValue;
}
    
$error $xmlpath->query("/yandexsearch/response/error");
    if (
$error->length 0){
    
$error $error ->item(0)->nodeValue;
    }
    else
    {
    
$error '';
    }

    
$reqid $xmlpath->query("/yandexsearch/response/reqid");
    if (
$reqid->length 0){
    
$reqid $reqid->item(0)->nodeValue;
    }
    
$items $xmlpath->query("/yandexsearch/response/results/grouping/group/doc");

if (
$error != '')
{
     print 
"Ошибка: " iconv("UTF-8""Windows-1251",$error);}
else{
print 
"<p style='font-size: 80%'>Результат поиска: страниц &mdash; <b>$found</b></p><br/>n";
print 
"<ol start=";
print 
$page 10 .  ">n";

foreach (
$items as $item) {

print 
"<li>";
$url $xmlpath -> query ('url'$item) -> item(0)->nodeValue;
print 
"<a href='" $url .  "'>" iconv("UTF-8""Windows-1251"$xmlpath -> query ('title'$item) -> item(0) -> nodeValue) .  "</a><br/>n";
print 
"<ul>";
$passages $xmlpath -> query('passages/passage'$item);
              
foreach (
$passages as $passage)
  {
   print 
"<li style='font-size: 80%'>".iconv("UTF-8""Windows-1251",$passage->nodeValue) .  "</li><br/>n";
  }
 print 
"<span style='color: gray; font-size: 80%'>" $url"</span>";
 print 
"</ul></li><br/>n";
                

}

print 
"</ol>n";




print_pager ($found$reqid$pageurlencode($query_search));            
 


}        
}
?>
</td>
<tr>
</table>

Андрей Друченко
у меня есть и вариант с методом POST, но как раз там получилось писанины больше. В общем — кому как более удобно тот так и пишет. На вкус и цвет товарищей нет. Суть данной статьи пролить свет на то как это ВООБЩЕ может делаться средствами PHP и дать почву для дальнейших совершенствований и модификаций кода, а не для тупого копирования оного в свои веб-приложения.

P.s. Если у вас есть POST вариант — можете поделиться и поместить его в комментарии, PHP код подсвечивается + делается автотипографика, так что выглядеть будет нормально. Синтаксис комментариев аналогичен WackoWiki (http://wackowiki.com)

Юрий
Да я не в обиду говорил..., посто прежде чем опубликовать исходники, надо проверять их работоспособность...
А если именно по коду, то метод GET для передачи параметров yandex`у, еще тот геморой, передача xml запроса методом POST, кажется мне более логичной.

Срипт работающий Андрей Друченко
Вышеприведенный код 100% рабочий. Просто для его запуска требуется еще кое-какие действия кроме copy-paste.

Ну дайте блин pedro
Может кто то всё таки поделиться работающим???

Скрипт подправлен Андрей Друченко
Толку от примера работы «нормального скрипта» – если его исходники нельзя посмотреть никоим образом? И всякие подробности о том под что и с использованием чего он написан не играют никакой роли.

Вот пример работы нормального php скрипта Юрий
Вот пример работы нормального php скрипта. В отличии от вышеприведенного 100% рабочий. Написан для php5 т.к. использует уже DOM.
Пример работы можно увидеть на сайте http://drivers.freeware32.ru

Ваше имя *
А вы не робот?

Заголовок
Комментарий *
* — поле обязательно для заполнения
PHP/HTML код для подсветки надо заключать в %%(php/html)<? ?>.