Приветствую вас, многоуважаемые разработчики. Сегодня речь пойдет опять о Yandex и его сервисе XML, о котором я уже упоминал в заметке о Yandex XML, т.к. нашей веб студии для собственных нужд понадобился сей компонент, но немного расширенный, модернизированный и использующий Zend Framework. Сейчас он будет более объектно-ориентированный и удобный в использовании.
Набросал для себя первую версию для всей грязной работы, который умеет только получать позицию сайт по определенному ключевому слову, а большего и не нужно.
<?phpset_time_limit(0);/** * YandexParser is class what helps getting position of your site by query string * * @author vredniy (dnd.pliz@gmail.com) */classModel_YandexParser{/** * @var string */protected$_query='';/** * @var string */protected$_host='';/** * @var int */protected$_pageLimit=50;private$_username='';private$_key='';/** * * @param string $query query string * @param string $host host string * @param int $pageLimit page limit */publicfunction__construct($query,$host,$pageLimit=null,$username=null,$key=null){if(isset($query))$this->_query=htmlspecialchars($query);if(isset($host))$this->_host=preg_replace('[^http://|www\.]','',htmlspecialchars($host));if(isset($pageLimit))$this->_pageLimit=is_int($pageLimit)?$pageLimit:(int)$pageLimit;if(isset($username))$this->_username=$username;if(isset($key))$this->_key=$key;}/** * send request * * @return int|string */publicfunctionrequest(){$page=0;do{if($result=$this->_doRoutine($this->_query,$this->_host,$page++))break;}while($page*10<$this->_pageLimit);if(false==$result)return'Nothing Found';return$result;}/** * does all dirty work * * @param string $query * @param string $host * @param int $page * @throws Zend_Http_Client_Exception * @return false|int */protectedfunction_doRoutine($query,$host,$page){if(10*$page>=$this->_pageLimit)returnfalse;$doc="<?xml version='1.0' encoding='utf-8'?> <request> <query>$query</query> <page>$page</page> <maxpassages>0</maxpassages> <groupings> <groupby attr='d' mode='deep' groups-on-page='10' docs-in-group='1' curcateg='-1'/> </groupings> </request>";$uri='http://xmlsearch.yandex.ru/xmlsearch';if($this->_username)$uri.='?user='.$this->_username;if($this->_key)$uri.='&key='.$this->_key;$httpClient=newZend_Http_Client($uri);$response=$httpClient->setRawData($doc,'text/xml')->request('POST');if($response->isSuccessful()){$zQ=newZend_Dom_Query($response->getBody());$result=$zQ->queryXpath('/yandexsearch/response/results/grouping/group/doc/url');$innerHTML='';$counter=10*$page;foreach($resultas$r){$children=$r->childNodes;$counter++;foreach($childrenas$child)if(false!==strpos($child->ownerDocument->saveXml($child),$host))return$counter;}}else{thrownewZend_Http_Client_Exception($response->getHeadersAsString(true,'<br>'));}returnfalse;}}?>
Конструктор (строки 34-47) заполняет внутренние свойства класса, которые нам понадобятся для дальнейшей работы.
Метод Model_YandexParser::request() (54-65) запускает цикл по всей глубине поиска заданного сайта и возвращает значение.
Защищенный метод Model_YandexParser::_doRoutine(…) (76-120) выполняет всю грязную работу по отправлению запроса, получению ответа от Yandex’а и поиска подходящего нам сайта. Нужно будет, как будет больше времени, дописать проверка на ошибки и вывод соответствующих сообщений.
Дальше регистрируем свой IP (требования Yandex’а) тут и запускаем наш поиск в каком-нибудь из наших экшнов. К примеру так