воскресенье, 16 сентября 2012 г.

Получение тИЦ сайта от Yandex

Данная задача возникает когда вы собираетесь писать какой либо анализатор сайта.
Казалось бы, что проще... парсить yandex по ссылке http://yaca.yandex.ru/yca/cy/ch/blogger.com/
Но к сожалению Яндекс очень привередливый, и не любит когда его парсят. И если с вашего сервера вырастит трафик то вас или попросят  ввести капчу или вовсе забанят.



В поисках решения этого вопроса наткнулся на денежку от яндекса.


И вроде бы он отдает ее всем желающим без какой либо проверки, но как получить тИЦ с картинки ? Пришло в голову, что для проверки целостности файла используется его хеш, и на PHP есть функция которая позволяет получить этот самый хэш нашей денежки md5(). И если мы скачаем на сервер картинки с Яндекса зная какой тиц на них нарисован и сравним их хеш с хешем картинки для определенного сайта мы сможем определить его тиц.


Опять же встала проблема, надо перебрать сайты со всеми возможными значениями тИЦ, чтобы собрать все картинки в базу для сравнения. Тут пришел на помощь всеми не любимый Яндекс бар. Он общается с сервером яндекса по средствам XML сообщений и для получения тИЦ сайта достаточно выполнить GET запрос по адресу http://bar-navig.yandex.ru/u?ver=2&show=32&url=http://blogger.com. Конечно тут нас яндекс сможет так же забанить при очень частых обращениях. но использую первый способ мы постараемся этого избежать. Запрос к серверу я так же постарался немного украсит заголовками при помощи библиотеки curl, но это совсем другая история.

Объединив эти два способа получение тИЦ, вышел универсальный скрипт.

Мы запрашиваем картинку для указанного сайта, проверяем ее хеш с теми картинками что есть в базе, если находим то водим искомый тИЦ, если нет, то обращаемся к яндекс xml получаем реальный тИЦ сайта и дополняем нашу базу "денежкой" для этого значения тИЦ.

Получается минимум обращения за XML и динамическое пополнение базы с картинками.
Тем более если Яндекс вдруг решит обновить дизайн картинок то скрипт обновит базу новыми.

Для хранения всех картинок не придется даже использовать базу данный, я просто их сохраняю с именем, соответствующие значению тИЦ.
В общем все просто. Вот и полученная функция.

function check_tic($host,$xml)
{
 // Ссылка на получение денюжки
 $cy_tpl = 'http://yandex.ru/cycounter?';
 //массив хэшей уже имеющихся денежек
 $md5_hashes = array();
 //сами картинки
 $files = glob('cy/*.gif');
 foreach($files as $file)
 {
  $md5 = md5_file($file);
  $name = basename($file, '.gif');
  // сохранение MD5 всех файлов в массив
  // соответствие тиц и MD5 хеша
  $md5_hashes[$md5] = $name;
 }
  // определение пути к денежке сайта
  $cy_url = $cy_tpl.$host;
  // чтение денежки с сервера яндекса
  $fp = fopen($cy_url, 'r');
  if($fp)
  {
   $image = '';
   while(!feof($fp))
    $image .= fread($fp, 1024);
   fclose($fp);
    }
   // определение MD5 полученной картинки
   $md5 = md5($image);
    //если нет нужной картинки, скачиваем ее беря тиц с яндекса bar-navig.yandex.ru
    if (!isset($md5_hashes[$md5])){
        $new_tic = cy($xml);
        $openedfile = fopen('cy_buttons/'.$new_tic.'.gif', "w");
        //сохраняем полученную картинку, на будущее =)
        fwrite($openedfile, $image);
        fclose($openedfile);
        // а вот и искомый тиц!
        $tic = $new_tic;
    }else{
    // а вот и искомый тиц!
    $tic = $md5_hashes[$md5];
    }
 return $tic;
}


Отдельно я вынес функции парсинга XML от Яндекса:
 Как получить сам XML надеюсь додумаете сами.
function cy($xml){
        preg_match("/value=\"(.\d*)\"/", $xml, $tic);
        return($tic[1]!=""?$tic[1]:0);
    }














Комментариев нет:

Отправить комментарий