Приветствую вас, многоуважаемые разработчики. Сегодня речь пойдет опять о Yandex и его сервисе XML, но немного расширенный, модернизированный и использующий Zend Framework. Сейчас он будет более объектно-ориентированный и удобный в использовании.
Набросал для себя первую версию для всей грязной работы, который умеет только получать позицию сайт по определенному ключевому слову, а большего и не нужно.
<?php
set_time_limit(0);
/**
* YandexParser is class what helps getting position of your site by query string
*
* @author vredniy (dnd.pliz@gmail.com)
*/
class Model_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
*/
public function __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
*/
public function request()
{
$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
*/
protected function _doRoutine($query, $host, $page)
{
if (10 * $page >= $this->_pageLimit)
return false;
$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 = new Zend_Http_Client($uri);
$response = $httpClient
->setRawData($doc, 'text/xml')
->request('POST');
if ($response->isSuccessful()) {
$zQ = new Zend_Dom_Query($response->getBody());
$result = $zQ->queryXpath('/yandexsearch/response/results/grouping/group/doc/url');
$innerHTML = '';
$counter = 10 * $page;
foreach($result as $r) {
$children = $r->childNodes;
$counter++;
foreach($children as $child)
if (false !== strpos($child->ownerDocument->saveXml($child), $host))
return $counter;
}
} else {
throw new Zend_Http_Client_Exception($response->getHeadersAsString(true, '<br>'));
}
return false;
}
}
?>
Конструктор (строки 34-47) заполняет внутренние свойства класса, которые нам понадобятся для дальнейшей работы.
Метод Model_YandexParser::request() (54-65) запускает цикл по всей глубине поиска заданного сайта и возвращает значение.
Защищенный метод Model_YandexParser::_doRoutine(…) (76-120) выполняет всю грязную работу по отправлению запроса, получению ответа от Yandex’а и поиска подходящего нам сайта. Нужно будет, как будет больше времени, дописать проверка на ошибки и вывод соответствующих сообщений.
Дальше регистрируем свой IP (требования Yandex’а) тут и запускаем наш поиск в каком-нибудь из наших экшнов. К примеру так
public function indexAction()
{
$yandex = new Model_YandexParser(
'голая Викки Блоуз',
'wowboobs.ru',
1000,
'username',
'INSERT_HERE_YOUR_SECRET_KEY'
);
$result = $yandex->request();
var_dump($result);
}
И наслаждаемся результатом